blob: 8ac95575d7835c47bbd1d9dd0c94c821c5e735ce [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -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
25import android.bluetooth.BluetoothDevice;
26import android.bluetooth.IBluetoothDevice;
27import android.content.BroadcastReceiver;
28import android.content.ComponentName;
29import android.content.ContentResolver;
30import android.content.Context;
31import android.content.ContextWrapper;
32import android.content.IContentProvider;
33import android.content.Intent;
34import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070035import android.content.IIntentReceiver;
36import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.ReceiverCallNotAllowedException;
38import android.content.ServiceConnection;
39import android.content.SharedPreferences;
40import android.content.pm.ActivityInfo;
41import android.content.pm.ApplicationInfo;
42import android.content.pm.ComponentInfo;
43import android.content.pm.IPackageDataObserver;
44import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.content.pm.IPackageInstallObserver;
46import 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;
59import android.database.sqlite.SQLiteDatabase;
60import android.database.sqlite.SQLiteDatabase.CursorFactory;
61import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.graphics.drawable.Drawable;
63import android.hardware.SensorManager;
64import android.location.ILocationManager;
65import android.location.LocationManager;
66import android.media.AudioManager;
67import android.net.ConnectivityManager;
68import android.net.IConnectivityManager;
69import android.net.Uri;
70import android.net.wifi.IWifiManager;
71import android.net.wifi.WifiManager;
72import android.os.Binder;
73import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.os.FileUtils;
75import android.os.Handler;
76import android.os.IBinder;
77import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070078import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.os.PowerManager;
80import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070081import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.os.ServiceManager;
83import android.os.Vibrator;
84import android.os.FileUtils.FileStatus;
85import android.telephony.TelephonyManager;
86import android.text.ClipboardManager;
87import android.util.AndroidRuntimeException;
88import android.util.Log;
89import android.view.ContextThemeWrapper;
90import android.view.LayoutInflater;
91import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070092import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070094import android.accounts.AccountManager;
95import android.accounts.IAccountManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import java.io.File;
98import java.io.FileInputStream;
99import java.io.FileNotFoundException;
100import java.io.FileOutputStream;
101import java.io.IOException;
102import java.io.InputStream;
103import java.lang.ref.WeakReference;
104import java.util.ArrayList;
105import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700106import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import java.util.Iterator;
108import java.util.List;
109import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700110import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700111import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import java.util.Map.Entry;
113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114class ReceiverRestrictedContext extends ContextWrapper {
115 ReceiverRestrictedContext(Context base) {
116 super(base);
117 }
118
119 @Override
120 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
121 return registerReceiver(receiver, filter, null, null);
122 }
123
124 @Override
125 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
126 String broadcastPermission, Handler scheduler) {
127 throw new ReceiverCallNotAllowedException(
128 "IntentReceiver components are not allowed to register to receive intents");
129 //ex.fillInStackTrace();
130 //Log.e("IntentReceiver", ex.getMessage(), ex);
131 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
132 // scheduler);
133 }
134
135 @Override
136 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
137 throw new ReceiverCallNotAllowedException(
138 "IntentReceiver components are not allowed to bind to services");
139 //ex.fillInStackTrace();
140 //Log.e("IntentReceiver", ex.getMessage(), ex);
141 //return mContext.bindService(service, interfaceName, conn, flags);
142 }
143}
144
145/**
146 * Common implementation of Context API, which Activity and other application
147 * classes inherit.
148 */
149class ApplicationContext extends Context {
150 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700151 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 private final static boolean DEBUG_ICONS = false;
153
154 private static final Object sSync = new Object();
Fred Quintana60307342009-03-24 22:48:12 -0700155 private static AccountManager sAccountManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 private static AlarmManager sAlarmManager;
157 private static PowerManager sPowerManager;
158 private static ConnectivityManager sConnectivityManager;
159 private static WifiManager sWifiManager;
160 private static LocationManager sLocationManager;
161 private static boolean sIsBluetoothDeviceCached = false;
162 private static BluetoothDevice sBluetoothDevice;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
164 new HashMap<File, SharedPreferencesImpl>();
165
166 private AudioManager mAudioManager;
167 /*package*/ ActivityThread.PackageInfo mPackageInfo;
168 private Resources mResources;
169 /*package*/ ActivityThread mMainThread;
170 private Context mOuterContext;
171 private IBinder mActivityToken = null;
172 private ApplicationContentResolver mContentResolver;
173 private int mThemeResource = 0;
174 private Resources.Theme mTheme = null;
175 private PackageManager mPackageManager;
176 private NotificationManager mNotificationManager = null;
177 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700178 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 private Context mReceiverRestrictedContext = null;
180 private SearchManager mSearchManager = null;
181 private SensorManager mSensorManager = null;
182 private Vibrator mVibrator = null;
183 private LayoutInflater mLayoutInflater = null;
184 private StatusBarManager mStatusBarManager = null;
185 private TelephonyManager mTelephonyManager = null;
186 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700187 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
189 private final Object mSync = new Object();
190
191 private File mDatabasesDir;
192 private File mPreferencesDir;
193 private File mFilesDir;
194
195
196 private File mCacheDir;
197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 private static long sInstanceCount = 0;
199
200 private static final String[] EMPTY_FILE_LIST = {};
201
202 @Override
203 protected void finalize() throws Throwable {
204 super.finalize();
205 --sInstanceCount;
206 }
207
208 public static long getInstanceCount() {
209 return sInstanceCount;
210 }
211
212 @Override
213 public AssetManager getAssets() {
214 return mResources.getAssets();
215 }
216
217 @Override
218 public Resources getResources() {
219 return mResources;
220 }
221
222 @Override
223 public PackageManager getPackageManager() {
224 if (mPackageManager != null) {
225 return mPackageManager;
226 }
227
228 IPackageManager pm = ActivityThread.getPackageManager();
229 if (pm != null) {
230 // Doesn't matter if we make more than one instance.
231 return (mPackageManager = new ApplicationPackageManager(this, pm));
232 }
233
234 return null;
235 }
236
237 @Override
238 public ContentResolver getContentResolver() {
239 return mContentResolver;
240 }
241
242 @Override
243 public Looper getMainLooper() {
244 return mMainThread.getLooper();
245 }
246
247 @Override
248 public Context getApplicationContext() {
249 return mMainThread.getApplication();
250 }
251
252 @Override
253 public void setTheme(int resid) {
254 mThemeResource = resid;
255 }
256
257 @Override
258 public Resources.Theme getTheme() {
259 if (mTheme == null) {
260 if (mThemeResource == 0) {
261 mThemeResource = com.android.internal.R.style.Theme;
262 }
263 mTheme = mResources.newTheme();
264 mTheme.applyStyle(mThemeResource, true);
265 }
266 return mTheme;
267 }
268
269 @Override
270 public ClassLoader getClassLoader() {
271 return mPackageInfo != null ?
272 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
273 }
274
275 @Override
276 public String getPackageName() {
277 if (mPackageInfo != null) {
278 return mPackageInfo.getPackageName();
279 }
280 throw new RuntimeException("Not supported in system context");
281 }
282
283 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700284 public ApplicationInfo getApplicationInfo() {
285 if (mPackageInfo != null) {
286 return mPackageInfo.getApplicationInfo();
287 }
288 throw new RuntimeException("Not supported in system context");
289 }
290
291 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 public String getPackageResourcePath() {
293 if (mPackageInfo != null) {
294 return mPackageInfo.getResDir();
295 }
296 throw new RuntimeException("Not supported in system context");
297 }
298
299 @Override
300 public String getPackageCodePath() {
301 if (mPackageInfo != null) {
302 return mPackageInfo.getAppDir();
303 }
304 throw new RuntimeException("Not supported in system context");
305 }
306
307 private static File makeBackupFile(File prefsFile) {
308 return new File(prefsFile.getPath() + ".bak");
309 }
310
Joe Onorato23ecae32009-06-10 17:07:15 -0700311 public File getSharedPrefsFile(String name) {
312 return makeFilename(getPreferencesDir(), name + ".xml");
313 }
314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 @Override
316 public SharedPreferences getSharedPreferences(String name, int mode) {
317 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700318 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 synchronized (sSharedPrefs) {
320 sp = sSharedPrefs.get(f);
321 if (sp != null && !sp.hasFileChanged()) {
322 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
323 return sp;
324 }
325 }
326
327 FileInputStream str = null;
328 File backup = makeBackupFile(f);
329 if (backup.exists()) {
330 f.delete();
331 backup.renameTo(f);
332 }
333
334 // Debugging
335 if (f.exists() && !f.canRead()) {
336 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
337 }
338
339 Map map = null;
340 if (f.exists() && f.canRead()) {
341 try {
342 str = new FileInputStream(f);
343 map = XmlUtils.readMapXml(str);
344 str.close();
345 } catch (org.xmlpull.v1.XmlPullParserException e) {
346 Log.w(TAG, "getSharedPreferences", e);
347 } catch (FileNotFoundException e) {
348 Log.w(TAG, "getSharedPreferences", e);
349 } catch (IOException e) {
350 Log.w(TAG, "getSharedPreferences", e);
351 }
352 }
353
354 synchronized (sSharedPrefs) {
355 if (sp != null) {
356 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
357 sp.replace(map);
358 } else {
359 sp = sSharedPrefs.get(f);
360 if (sp == null) {
361 sp = new SharedPreferencesImpl(f, mode, map);
362 sSharedPrefs.put(f, sp);
363 }
364 }
365 return sp;
366 }
367 }
368
369 private File getPreferencesDir() {
370 synchronized (mSync) {
371 if (mPreferencesDir == null) {
372 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
373 }
374 return mPreferencesDir;
375 }
376 }
377
378 @Override
379 public FileInputStream openFileInput(String name)
380 throws FileNotFoundException {
381 File f = makeFilename(getFilesDir(), name);
382 return new FileInputStream(f);
383 }
384
385 @Override
386 public FileOutputStream openFileOutput(String name, int mode)
387 throws FileNotFoundException {
388 final boolean append = (mode&MODE_APPEND) != 0;
389 File f = makeFilename(getFilesDir(), name);
390 try {
391 FileOutputStream fos = new FileOutputStream(f, append);
392 setFilePermissionsFromMode(f.getPath(), mode, 0);
393 return fos;
394 } catch (FileNotFoundException e) {
395 }
396
397 File parent = f.getParentFile();
398 parent.mkdir();
399 FileUtils.setPermissions(
400 parent.getPath(),
401 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
402 -1, -1);
403 FileOutputStream fos = new FileOutputStream(f, append);
404 setFilePermissionsFromMode(f.getPath(), mode, 0);
405 return fos;
406 }
407
408 @Override
409 public boolean deleteFile(String name) {
410 File f = makeFilename(getFilesDir(), name);
411 return f.delete();
412 }
413
414 @Override
415 public File getFilesDir() {
416 synchronized (mSync) {
417 if (mFilesDir == null) {
418 mFilesDir = new File(getDataDirFile(), "files");
419 }
420 if (!mFilesDir.exists()) {
421 if(!mFilesDir.mkdirs()) {
422 Log.w(TAG, "Unable to create files directory");
423 return null;
424 }
425 FileUtils.setPermissions(
426 mFilesDir.getPath(),
427 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
428 -1, -1);
429 }
430 return mFilesDir;
431 }
432 }
433
434 @Override
435 public File getCacheDir() {
436 synchronized (mSync) {
437 if (mCacheDir == null) {
438 mCacheDir = new File(getDataDirFile(), "cache");
439 }
440 if (!mCacheDir.exists()) {
441 if(!mCacheDir.mkdirs()) {
442 Log.w(TAG, "Unable to create cache directory");
443 return null;
444 }
445 FileUtils.setPermissions(
446 mCacheDir.getPath(),
447 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
448 -1, -1);
449 }
450 }
451 return mCacheDir;
452 }
453
454
455 @Override
456 public File getFileStreamPath(String name) {
457 return makeFilename(getFilesDir(), name);
458 }
459
460 @Override
461 public String[] fileList() {
462 final String[] list = getFilesDir().list();
463 return (list != null) ? list : EMPTY_FILE_LIST;
464 }
465
466 @Override
467 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
468 File dir = getDatabasesDir();
469 if (!dir.isDirectory() && dir.mkdir()) {
470 FileUtils.setPermissions(dir.getPath(),
471 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
472 -1, -1);
473 }
474
475 File f = makeFilename(dir, name);
476 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
477 setFilePermissionsFromMode(f.getPath(), mode, 0);
478 return db;
479 }
480
481 @Override
482 public boolean deleteDatabase(String name) {
483 try {
484 File f = makeFilename(getDatabasesDir(), name);
485 return f.delete();
486 } catch (Exception e) {
487 }
488 return false;
489 }
490
491 @Override
492 public File getDatabasePath(String name) {
493 return makeFilename(getDatabasesDir(), name);
494 }
495
496 @Override
497 public String[] databaseList() {
498 final String[] list = getDatabasesDir().list();
499 return (list != null) ? list : EMPTY_FILE_LIST;
500 }
501
502
503 private File getDatabasesDir() {
504 synchronized (mSync) {
505 if (mDatabasesDir == null) {
506 mDatabasesDir = new File(getDataDirFile(), "databases");
507 }
508 if (mDatabasesDir.getPath().equals("databases")) {
509 mDatabasesDir = new File("/data/system");
510 }
511 return mDatabasesDir;
512 }
513 }
514
515 @Override
516 public Drawable getWallpaper() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700517 return getWallpaperManager().get();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 }
519
520 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700521 public Drawable peekWallpaper() {
522 return getWallpaperManager().peek();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 }
524
525 @Override
526 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700527 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 }
529
530 @Override
531 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700532 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 }
534
535 @Override
536 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700537 getWallpaperManager().set(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 }
539
540 @Override
541 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700542 getWallpaperManager().set(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 }
544
545 @Override
546 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700547 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 }
549
550 @Override
551 public void startActivity(Intent intent) {
552 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
553 throw new AndroidRuntimeException(
554 "Calling startActivity() from outside of an Activity "
555 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
556 + " Is this really what you want?");
557 }
558 mMainThread.getInstrumentation().execStartActivity(
559 getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
560 }
561
562 @Override
563 public void sendBroadcast(Intent intent) {
564 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
565 try {
566 ActivityManagerNative.getDefault().broadcastIntent(
567 mMainThread.getApplicationThread(), intent, resolvedType, null,
568 Activity.RESULT_OK, null, null, null, false, false);
569 } catch (RemoteException e) {
570 }
571 }
572
573 @Override
574 public void sendBroadcast(Intent intent, String receiverPermission) {
575 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
576 try {
577 ActivityManagerNative.getDefault().broadcastIntent(
578 mMainThread.getApplicationThread(), intent, resolvedType, null,
579 Activity.RESULT_OK, null, null, receiverPermission, false, false);
580 } catch (RemoteException e) {
581 }
582 }
583
584 @Override
585 public void sendOrderedBroadcast(Intent intent,
586 String receiverPermission) {
587 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
588 try {
589 ActivityManagerNative.getDefault().broadcastIntent(
590 mMainThread.getApplicationThread(), intent, resolvedType, null,
591 Activity.RESULT_OK, null, null, receiverPermission, true, false);
592 } catch (RemoteException e) {
593 }
594 }
595
596 @Override
597 public void sendOrderedBroadcast(Intent intent,
598 String receiverPermission, BroadcastReceiver resultReceiver,
599 Handler scheduler, int initialCode, String initialData,
600 Bundle initialExtras) {
601 IIntentReceiver rd = null;
602 if (resultReceiver != null) {
603 if (mPackageInfo != null) {
604 if (scheduler == null) {
605 scheduler = mMainThread.getHandler();
606 }
607 rd = mPackageInfo.getReceiverDispatcher(
608 resultReceiver, getOuterContext(), scheduler,
609 mMainThread.getInstrumentation(), false);
610 } else {
611 if (scheduler == null) {
612 scheduler = mMainThread.getHandler();
613 }
614 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
615 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
616 }
617 }
618 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
619 try {
620 ActivityManagerNative.getDefault().broadcastIntent(
621 mMainThread.getApplicationThread(), intent, resolvedType, rd,
622 initialCode, initialData, initialExtras, receiverPermission,
623 true, false);
624 } catch (RemoteException e) {
625 }
626 }
627
628 @Override
629 public void sendStickyBroadcast(Intent intent) {
630 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
631 try {
632 ActivityManagerNative.getDefault().broadcastIntent(
633 mMainThread.getApplicationThread(), intent, resolvedType, null,
634 Activity.RESULT_OK, null, null, null, false, true);
635 } catch (RemoteException e) {
636 }
637 }
638
639 @Override
640 public void removeStickyBroadcast(Intent intent) {
641 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
642 if (resolvedType != null) {
643 intent = new Intent(intent);
644 intent.setDataAndType(intent.getData(), resolvedType);
645 }
646 try {
647 ActivityManagerNative.getDefault().unbroadcastIntent(
648 mMainThread.getApplicationThread(), intent);
649 } catch (RemoteException e) {
650 }
651 }
652
653 @Override
654 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
655 return registerReceiver(receiver, filter, null, null);
656 }
657
658 @Override
659 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
660 String broadcastPermission, Handler scheduler) {
661 return registerReceiverInternal(receiver, filter, broadcastPermission,
662 scheduler, getOuterContext());
663 }
664
665 private Intent registerReceiverInternal(BroadcastReceiver receiver,
666 IntentFilter filter, String broadcastPermission,
667 Handler scheduler, Context context) {
668 IIntentReceiver rd = null;
669 if (receiver != null) {
670 if (mPackageInfo != null && context != null) {
671 if (scheduler == null) {
672 scheduler = mMainThread.getHandler();
673 }
674 rd = mPackageInfo.getReceiverDispatcher(
675 receiver, context, scheduler,
676 mMainThread.getInstrumentation(), true);
677 } else {
678 if (scheduler == null) {
679 scheduler = mMainThread.getHandler();
680 }
681 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
682 receiver, context, scheduler, null, false).getIIntentReceiver();
683 }
684 }
685 try {
686 return ActivityManagerNative.getDefault().registerReceiver(
687 mMainThread.getApplicationThread(),
688 rd, filter, broadcastPermission);
689 } catch (RemoteException e) {
690 return null;
691 }
692 }
693
694 @Override
695 public void unregisterReceiver(BroadcastReceiver receiver) {
696 if (mPackageInfo != null) {
697 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
698 getOuterContext(), receiver);
699 try {
700 ActivityManagerNative.getDefault().unregisterReceiver(rd);
701 } catch (RemoteException e) {
702 }
703 } else {
704 throw new RuntimeException("Not supported in system context");
705 }
706 }
707
708 @Override
709 public ComponentName startService(Intent service) {
710 try {
711 ComponentName cn = ActivityManagerNative.getDefault().startService(
712 mMainThread.getApplicationThread(), service,
713 service.resolveTypeIfNeeded(getContentResolver()));
714 if (cn != null && cn.getPackageName().equals("!")) {
715 throw new SecurityException(
716 "Not allowed to start service " + service
717 + " without permission " + cn.getClassName());
718 }
719 return cn;
720 } catch (RemoteException e) {
721 return null;
722 }
723 }
724
725 @Override
726 public boolean stopService(Intent service) {
727 try {
728 int res = ActivityManagerNative.getDefault().stopService(
729 mMainThread.getApplicationThread(), service,
730 service.resolveTypeIfNeeded(getContentResolver()));
731 if (res < 0) {
732 throw new SecurityException(
733 "Not allowed to stop service " + service);
734 }
735 return res != 0;
736 } catch (RemoteException e) {
737 return false;
738 }
739 }
740
741 @Override
742 public boolean bindService(Intent service, ServiceConnection conn,
743 int flags) {
744 IServiceConnection sd;
745 if (mPackageInfo != null) {
746 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
747 mMainThread.getHandler(), flags);
748 } else {
749 throw new RuntimeException("Not supported in system context");
750 }
751 try {
752 int res = ActivityManagerNative.getDefault().bindService(
753 mMainThread.getApplicationThread(), getActivityToken(),
754 service, service.resolveTypeIfNeeded(getContentResolver()),
755 sd, flags);
756 if (res < 0) {
757 throw new SecurityException(
758 "Not allowed to bind to service " + service);
759 }
760 return res != 0;
761 } catch (RemoteException e) {
762 return false;
763 }
764 }
765
766 @Override
767 public void unbindService(ServiceConnection conn) {
768 if (mPackageInfo != null) {
769 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
770 getOuterContext(), conn);
771 try {
772 ActivityManagerNative.getDefault().unbindService(sd);
773 } catch (RemoteException e) {
774 }
775 } else {
776 throw new RuntimeException("Not supported in system context");
777 }
778 }
779
780 @Override
781 public boolean startInstrumentation(ComponentName className,
782 String profileFile, Bundle arguments) {
783 try {
784 return ActivityManagerNative.getDefault().startInstrumentation(
785 className, profileFile, 0, arguments, null);
786 } catch (RemoteException e) {
787 // System has crashed, nothing we can do.
788 }
789 return false;
790 }
791
792 @Override
793 public Object getSystemService(String name) {
794 if (WINDOW_SERVICE.equals(name)) {
795 return WindowManagerImpl.getDefault();
796 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
797 synchronized (mSync) {
798 LayoutInflater inflater = mLayoutInflater;
799 if (inflater != null) {
800 return inflater;
801 }
802 mLayoutInflater = inflater =
803 PolicyManager.makeNewLayoutInflater(getOuterContext());
804 return inflater;
805 }
806 } else if (ACTIVITY_SERVICE.equals(name)) {
807 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700808 } else if (INPUT_METHOD_SERVICE.equals(name)) {
809 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 } else if (ALARM_SERVICE.equals(name)) {
811 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700812 } else if (ACCOUNT_SERVICE.equals(name)) {
813 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 } else if (POWER_SERVICE.equals(name)) {
815 return getPowerManager();
816 } else if (CONNECTIVITY_SERVICE.equals(name)) {
817 return getConnectivityManager();
818 } else if (WIFI_SERVICE.equals(name)) {
819 return getWifiManager();
820 } else if (NOTIFICATION_SERVICE.equals(name)) {
821 return getNotificationManager();
822 } else if (KEYGUARD_SERVICE.equals(name)) {
823 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700824 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
825 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 } else if (LOCATION_SERVICE.equals(name)) {
827 return getLocationManager();
828 } else if (SEARCH_SERVICE.equals(name)) {
829 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700830 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 return getSensorManager();
832 } else if (BLUETOOTH_SERVICE.equals(name)) {
833 return getBluetoothDevice();
834 } else if (VIBRATOR_SERVICE.equals(name)) {
835 return getVibrator();
836 } else if (STATUS_BAR_SERVICE.equals(name)) {
837 synchronized (mSync) {
838 if (mStatusBarManager == null) {
839 mStatusBarManager = new StatusBarManager(getOuterContext());
840 }
841 return mStatusBarManager;
842 }
843 } else if (AUDIO_SERVICE.equals(name)) {
844 return getAudioManager();
845 } else if (TELEPHONY_SERVICE.equals(name)) {
846 return getTelephonyManager();
847 } else if (CLIPBOARD_SERVICE.equals(name)) {
848 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700849 } else if (WALLPAPER_SERVICE.equals(name)) {
850 return getWallpaperManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 }
852
853 return null;
854 }
855
Fred Quintana60307342009-03-24 22:48:12 -0700856 private AccountManager getAccountManager() {
857 synchronized (sSync) {
858 if (sAccountManager == null) {
859 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
860 IAccountManager service = IAccountManager.Stub.asInterface(b);
861 sAccountManager = new AccountManager(this, service);
862 }
863 }
864 return sAccountManager;
865 }
866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 private ActivityManager getActivityManager() {
868 synchronized (mSync) {
869 if (mActivityManager == null) {
870 mActivityManager = new ActivityManager(getOuterContext(),
871 mMainThread.getHandler());
872 }
873 }
874 return mActivityManager;
875 }
876
877 private AlarmManager getAlarmManager() {
878 synchronized (sSync) {
879 if (sAlarmManager == null) {
880 IBinder b = ServiceManager.getService(ALARM_SERVICE);
881 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
882 sAlarmManager = new AlarmManager(service);
883 }
884 }
885 return sAlarmManager;
886 }
887
888 private PowerManager getPowerManager() {
889 synchronized (sSync) {
890 if (sPowerManager == null) {
891 IBinder b = ServiceManager.getService(POWER_SERVICE);
892 IPowerManager service = IPowerManager.Stub.asInterface(b);
893 sPowerManager = new PowerManager(service, mMainThread.getHandler());
894 }
895 }
896 return sPowerManager;
897 }
898
899 private ConnectivityManager getConnectivityManager()
900 {
901 synchronized (sSync) {
902 if (sConnectivityManager == null) {
903 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
904 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
905 sConnectivityManager = new ConnectivityManager(service);
906 }
907 }
908 return sConnectivityManager;
909 }
910
911 private WifiManager getWifiManager()
912 {
913 synchronized (sSync) {
914 if (sWifiManager == null) {
915 IBinder b = ServiceManager.getService(WIFI_SERVICE);
916 IWifiManager service = IWifiManager.Stub.asInterface(b);
917 sWifiManager = new WifiManager(service, mMainThread.getHandler());
918 }
919 }
920 return sWifiManager;
921 }
922
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700923 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 synchronized (mSync) {
925 if (mNotificationManager == null) {
926 mNotificationManager = new NotificationManager(
927 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
928 mMainThread.getHandler());
929 }
930 }
931 return mNotificationManager;
932 }
933
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700934 private WallpaperManager getWallpaperManager() {
935 synchronized (mSync) {
936 if (mWallpaperManager == null) {
937 mWallpaperManager = new WallpaperManager(getOuterContext(),
938 mMainThread.getHandler());
939 }
940 }
941 return mWallpaperManager;
942 }
943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 private TelephonyManager getTelephonyManager() {
945 synchronized (mSync) {
946 if (mTelephonyManager == null) {
947 mTelephonyManager = new TelephonyManager(getOuterContext());
948 }
949 }
950 return mTelephonyManager;
951 }
952
953 private ClipboardManager getClipboardManager() {
954 synchronized (mSync) {
955 if (mClipboardManager == null) {
956 mClipboardManager = new ClipboardManager(getOuterContext(),
957 mMainThread.getHandler());
958 }
959 }
960 return mClipboardManager;
961 }
962
963 private LocationManager getLocationManager() {
964 synchronized (sSync) {
965 if (sLocationManager == null) {
966 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
967 ILocationManager service = ILocationManager.Stub.asInterface(b);
968 sLocationManager = new LocationManager(service);
969 }
970 }
971 return sLocationManager;
972 }
973
974 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 synchronized (mSync) {
976 if (mSearchManager == null) {
977 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
978 }
979 }
980 return mSearchManager;
981 }
982
983 private BluetoothDevice getBluetoothDevice() {
984 if (sIsBluetoothDeviceCached) {
985 return sBluetoothDevice;
986 }
987 synchronized (sSync) {
988 IBinder b = ServiceManager.getService(BLUETOOTH_SERVICE);
989 if (b == null) {
990 sBluetoothDevice = null;
991 } else {
992 IBluetoothDevice service = IBluetoothDevice.Stub.asInterface(b);
993 sBluetoothDevice = new BluetoothDevice(service);
994 }
995 sIsBluetoothDeviceCached = true;
996 }
997 return sBluetoothDevice;
998 }
999
1000 private SensorManager getSensorManager() {
1001 synchronized (mSync) {
1002 if (mSensorManager == null) {
1003 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1004 }
1005 }
1006 return mSensorManager;
1007 }
1008
1009 private Vibrator getVibrator() {
1010 synchronized (mSync) {
1011 if (mVibrator == null) {
1012 mVibrator = new Vibrator();
1013 }
1014 }
1015 return mVibrator;
1016 }
1017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 private AudioManager getAudioManager()
1019 {
1020 if (mAudioManager == null) {
1021 mAudioManager = new AudioManager(this);
1022 }
1023 return mAudioManager;
1024 }
1025
1026 @Override
1027 public int checkPermission(String permission, int pid, int uid) {
1028 if (permission == null) {
1029 throw new IllegalArgumentException("permission is null");
1030 }
1031
1032 if (!Process.supportsProcesses()) {
1033 return PackageManager.PERMISSION_GRANTED;
1034 }
1035 try {
1036 return ActivityManagerNative.getDefault().checkPermission(
1037 permission, pid, uid);
1038 } catch (RemoteException e) {
1039 return PackageManager.PERMISSION_DENIED;
1040 }
1041 }
1042
1043 @Override
1044 public int checkCallingPermission(String permission) {
1045 if (permission == null) {
1046 throw new IllegalArgumentException("permission is null");
1047 }
1048
1049 if (!Process.supportsProcesses()) {
1050 return PackageManager.PERMISSION_GRANTED;
1051 }
1052 int pid = Binder.getCallingPid();
1053 if (pid != Process.myPid()) {
1054 return checkPermission(permission, pid,
1055 Binder.getCallingUid());
1056 }
1057 return PackageManager.PERMISSION_DENIED;
1058 }
1059
1060 @Override
1061 public int checkCallingOrSelfPermission(String permission) {
1062 if (permission == null) {
1063 throw new IllegalArgumentException("permission is null");
1064 }
1065
1066 return checkPermission(permission, Binder.getCallingPid(),
1067 Binder.getCallingUid());
1068 }
1069
1070 private void enforce(
1071 String permission, int resultOfCheck,
1072 boolean selfToo, int uid, String message) {
1073 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1074 throw new SecurityException(
1075 (message != null ? (message + ": ") : "") +
1076 (selfToo
1077 ? "Neither user " + uid + " nor current process has "
1078 : "User " + uid + " does not have ") +
1079 permission +
1080 ".");
1081 }
1082 }
1083
1084 public void enforcePermission(
1085 String permission, int pid, int uid, String message) {
1086 enforce(permission,
1087 checkPermission(permission, pid, uid),
1088 false,
1089 uid,
1090 message);
1091 }
1092
1093 public void enforceCallingPermission(String permission, String message) {
1094 enforce(permission,
1095 checkCallingPermission(permission),
1096 false,
1097 Binder.getCallingUid(),
1098 message);
1099 }
1100
1101 public void enforceCallingOrSelfPermission(
1102 String permission, String message) {
1103 enforce(permission,
1104 checkCallingOrSelfPermission(permission),
1105 true,
1106 Binder.getCallingUid(),
1107 message);
1108 }
1109
1110 @Override
1111 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1112 try {
1113 ActivityManagerNative.getDefault().grantUriPermission(
1114 mMainThread.getApplicationThread(), toPackage, uri,
1115 modeFlags);
1116 } catch (RemoteException e) {
1117 }
1118 }
1119
1120 @Override
1121 public void revokeUriPermission(Uri uri, int modeFlags) {
1122 try {
1123 ActivityManagerNative.getDefault().revokeUriPermission(
1124 mMainThread.getApplicationThread(), uri,
1125 modeFlags);
1126 } catch (RemoteException e) {
1127 }
1128 }
1129
1130 @Override
1131 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1132 if (!Process.supportsProcesses()) {
1133 return PackageManager.PERMISSION_GRANTED;
1134 }
1135 try {
1136 return ActivityManagerNative.getDefault().checkUriPermission(
1137 uri, pid, uid, modeFlags);
1138 } catch (RemoteException e) {
1139 return PackageManager.PERMISSION_DENIED;
1140 }
1141 }
1142
1143 @Override
1144 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1145 if (!Process.supportsProcesses()) {
1146 return PackageManager.PERMISSION_GRANTED;
1147 }
1148 int pid = Binder.getCallingPid();
1149 if (pid != Process.myPid()) {
1150 return checkUriPermission(uri, pid,
1151 Binder.getCallingUid(), modeFlags);
1152 }
1153 return PackageManager.PERMISSION_DENIED;
1154 }
1155
1156 @Override
1157 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1158 return checkUriPermission(uri, Binder.getCallingPid(),
1159 Binder.getCallingUid(), modeFlags);
1160 }
1161
1162 @Override
1163 public int checkUriPermission(Uri uri, String readPermission,
1164 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001165 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1167 + readPermission + " writePermission=" + writePermission
1168 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1169 }
1170 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1171 if (readPermission == null
1172 || checkPermission(readPermission, pid, uid)
1173 == PackageManager.PERMISSION_GRANTED) {
1174 return PackageManager.PERMISSION_GRANTED;
1175 }
1176 }
1177 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1178 if (writePermission == null
1179 || checkPermission(writePermission, pid, uid)
1180 == PackageManager.PERMISSION_GRANTED) {
1181 return PackageManager.PERMISSION_GRANTED;
1182 }
1183 }
1184 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1185 : PackageManager.PERMISSION_DENIED;
1186 }
1187
1188 private String uriModeFlagToString(int uriModeFlags) {
1189 switch (uriModeFlags) {
1190 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1191 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1192 return "read and write";
1193 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1194 return "read";
1195 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1196 return "write";
1197 }
1198 throw new IllegalArgumentException(
1199 "Unknown permission mode flags: " + uriModeFlags);
1200 }
1201
1202 private void enforceForUri(
1203 int modeFlags, int resultOfCheck, boolean selfToo,
1204 int uid, Uri uri, String message) {
1205 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1206 throw new SecurityException(
1207 (message != null ? (message + ": ") : "") +
1208 (selfToo
1209 ? "Neither user " + uid + " nor current process has "
1210 : "User " + uid + " does not have ") +
1211 uriModeFlagToString(modeFlags) +
1212 " permission on " +
1213 uri +
1214 ".");
1215 }
1216 }
1217
1218 public void enforceUriPermission(
1219 Uri uri, int pid, int uid, int modeFlags, String message) {
1220 enforceForUri(
1221 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1222 false, uid, uri, message);
1223 }
1224
1225 public void enforceCallingUriPermission(
1226 Uri uri, int modeFlags, String message) {
1227 enforceForUri(
1228 modeFlags, checkCallingUriPermission(uri, modeFlags),
1229 false, Binder.getCallingUid(), uri, message);
1230 }
1231
1232 public void enforceCallingOrSelfUriPermission(
1233 Uri uri, int modeFlags, String message) {
1234 enforceForUri(
1235 modeFlags,
1236 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1237 Binder.getCallingUid(), uri, message);
1238 }
1239
1240 public void enforceUriPermission(
1241 Uri uri, String readPermission, String writePermission,
1242 int pid, int uid, int modeFlags, String message) {
1243 enforceForUri(modeFlags,
1244 checkUriPermission(
1245 uri, readPermission, writePermission, pid, uid,
1246 modeFlags),
1247 false,
1248 uid,
1249 uri,
1250 message);
1251 }
1252
1253 @Override
1254 public Context createPackageContext(String packageName, int flags)
1255 throws PackageManager.NameNotFoundException {
1256 if (packageName.equals("system") || packageName.equals("android")) {
1257 return new ApplicationContext(mMainThread.getSystemContext());
1258 }
1259
1260 ActivityThread.PackageInfo pi =
1261 mMainThread.getPackageInfo(packageName, flags);
1262 if (pi != null) {
1263 ApplicationContext c = new ApplicationContext();
Romain Guy870e09f2009-07-06 16:35:25 -07001264 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001265 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 if (c.mResources != null) {
1267 return c;
1268 }
1269 }
1270
1271 // Should be a better exception.
1272 throw new PackageManager.NameNotFoundException(
1273 "Application package " + packageName + " not found");
1274 }
1275
Romain Guy870e09f2009-07-06 16:35:25 -07001276 @Override
1277 public boolean isRestricted() {
1278 return mRestricted;
1279 }
1280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 private File getDataDirFile() {
1282 if (mPackageInfo != null) {
1283 return mPackageInfo.getDataDirFile();
1284 }
1285 throw new RuntimeException("Not supported in system context");
1286 }
1287
1288 @Override
1289 public File getDir(String name, int mode) {
1290 name = "app_" + name;
1291 File file = makeFilename(getDataDirFile(), name);
1292 if (!file.exists()) {
1293 file.mkdir();
1294 setFilePermissionsFromMode(file.getPath(), mode,
1295 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1296 }
1297 return file;
1298 }
1299
1300 static ApplicationContext createSystemContext(ActivityThread mainThread) {
1301 ApplicationContext context = new ApplicationContext();
1302 context.init(Resources.getSystem(), mainThread);
1303 return context;
1304 }
1305
1306 ApplicationContext() {
1307 ++sInstanceCount;
1308 mOuterContext = this;
1309 }
1310
1311 /**
1312 * Create a new ApplicationContext from an existing one. The new one
1313 * works and operates the same as the one it is copying.
1314 *
1315 * @param context Existing application context.
1316 */
1317 public ApplicationContext(ApplicationContext context) {
1318 ++sInstanceCount;
1319 mPackageInfo = context.mPackageInfo;
1320 mResources = context.mResources;
1321 mMainThread = context.mMainThread;
1322 mContentResolver = context.mContentResolver;
1323 mOuterContext = this;
1324 }
1325
1326 final void init(ActivityThread.PackageInfo packageInfo,
1327 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001328 init(packageInfo, activityToken, mainThread, null);
1329 }
1330
1331 final void init(ActivityThread.PackageInfo packageInfo,
1332 IBinder activityToken, ActivityThread mainThread,
1333 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 mPackageInfo = packageInfo;
1335 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001336
1337 if (container != null && container.getCompatibilityInfo().applicationScale !=
1338 mResources.getCompatibilityInfo().applicationScale) {
1339 if (DEBUG) {
1340 Log.d(TAG, "loaded context has different scaling. Using container's" +
1341 " compatiblity info:" + container.getDisplayMetrics());
1342 }
1343 mResources = mainThread.getTopLevelResources(
1344 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 mMainThread = mainThread;
1347 mContentResolver = new ApplicationContentResolver(this, mainThread);
1348
1349 setActivityToken(activityToken);
1350 }
1351
1352 final void init(Resources resources, ActivityThread mainThread) {
1353 mPackageInfo = null;
1354 mResources = resources;
1355 mMainThread = mainThread;
1356 mContentResolver = new ApplicationContentResolver(this, mainThread);
1357 }
1358
1359 final void scheduleFinalCleanup(String who, String what) {
1360 mMainThread.scheduleContextCleanup(this, who, what);
1361 }
1362
1363 final void performFinalCleanup(String who, String what) {
1364 //Log.i(TAG, "Cleanup up context: " + this);
1365 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1366 }
1367
1368 final Context getReceiverRestrictedContext() {
1369 if (mReceiverRestrictedContext != null) {
1370 return mReceiverRestrictedContext;
1371 }
1372 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1373 }
1374
1375 final void setActivityToken(IBinder token) {
1376 mActivityToken = token;
1377 }
1378
1379 final void setOuterContext(Context context) {
1380 mOuterContext = context;
1381 }
1382
1383 final Context getOuterContext() {
1384 return mOuterContext;
1385 }
1386
1387 final IBinder getActivityToken() {
1388 return mActivityToken;
1389 }
1390
1391 private static void setFilePermissionsFromMode(String name, int mode,
1392 int extraPermissions) {
1393 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1394 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1395 |extraPermissions;
1396 if ((mode&MODE_WORLD_READABLE) != 0) {
1397 perms |= FileUtils.S_IROTH;
1398 }
1399 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1400 perms |= FileUtils.S_IWOTH;
1401 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001402 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1404 + ", perms=0x" + Integer.toHexString(perms));
1405 }
1406 FileUtils.setPermissions(name, perms, -1, -1);
1407 }
1408
1409 private File makeFilename(File base, String name) {
1410 if (name.indexOf(File.separatorChar) < 0) {
1411 return new File(base, name);
1412 }
1413 throw new IllegalArgumentException(
1414 "File " + name + " contains a path separator");
1415 }
1416
1417 // ----------------------------------------------------------------------
1418 // ----------------------------------------------------------------------
1419 // ----------------------------------------------------------------------
1420
1421 private static final class ApplicationContentResolver extends ContentResolver {
1422 public ApplicationContentResolver(Context context,
1423 ActivityThread mainThread)
1424 {
1425 super(context);
1426 mMainThread = mainThread;
1427 }
1428
1429 @Override
1430 protected IContentProvider acquireProvider(Context context, String name)
1431 {
1432 return mMainThread.acquireProvider(context, name);
1433 }
1434
1435 @Override
1436 public boolean releaseProvider(IContentProvider provider)
1437 {
1438 return mMainThread.releaseProvider(provider);
1439 }
1440
1441 private final ActivityThread mMainThread;
1442 }
1443
1444 // ----------------------------------------------------------------------
1445 // ----------------------------------------------------------------------
1446 // ----------------------------------------------------------------------
1447
1448 /*package*/
1449 static final class ApplicationPackageManager extends PackageManager {
1450 @Override
1451 public PackageInfo getPackageInfo(String packageName, int flags)
1452 throws NameNotFoundException {
1453 try {
1454 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1455 if (pi != null) {
1456 return pi;
1457 }
1458 } catch (RemoteException e) {
1459 throw new RuntimeException("Package manager has died", e);
1460 }
1461
1462 throw new NameNotFoundException(packageName);
1463 }
1464
Mihai Predaeae850c2009-05-13 10:13:48 +02001465 @Override
1466 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 // First see if the package has an INFO activity; the existence of
1468 // such an activity is implied to be the desired front-door for the
1469 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001470 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1471 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001472 intentToResolve.setPackage(packageName);
1473 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001476 if (resolveInfo == null) {
1477 // reuse the intent instance
1478 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1479 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001480 intentToResolve.setPackage(packageName);
1481 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001483 if (resolveInfo == null) {
1484 return null;
1485 }
1486 Intent intent = new Intent(Intent.ACTION_MAIN);
1487 intent.setClassName(packageName, resolveInfo.activityInfo.name);
1488 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1489 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 @Override
1493 public int[] getPackageGids(String packageName)
1494 throws NameNotFoundException {
1495 try {
1496 int[] gids = mPM.getPackageGids(packageName);
1497 if (gids == null || gids.length > 0) {
1498 return gids;
1499 }
1500 } catch (RemoteException e) {
1501 throw new RuntimeException("Package manager has died", e);
1502 }
1503
1504 throw new NameNotFoundException(packageName);
1505 }
1506
1507 @Override
1508 public PermissionInfo getPermissionInfo(String name, int flags)
1509 throws NameNotFoundException {
1510 try {
1511 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1512 if (pi != null) {
1513 return pi;
1514 }
1515 } catch (RemoteException e) {
1516 throw new RuntimeException("Package manager has died", e);
1517 }
1518
1519 throw new NameNotFoundException(name);
1520 }
1521
1522 @Override
1523 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1524 throws NameNotFoundException {
1525 try {
1526 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1527 if (pi != null) {
1528 return pi;
1529 }
1530 } catch (RemoteException e) {
1531 throw new RuntimeException("Package manager has died", e);
1532 }
1533
1534 throw new NameNotFoundException(group);
1535 }
1536
1537 @Override
1538 public PermissionGroupInfo getPermissionGroupInfo(String name,
1539 int flags) throws NameNotFoundException {
1540 try {
1541 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1542 if (pgi != null) {
1543 return pgi;
1544 }
1545 } catch (RemoteException e) {
1546 throw new RuntimeException("Package manager has died", e);
1547 }
1548
1549 throw new NameNotFoundException(name);
1550 }
1551
1552 @Override
1553 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1554 try {
1555 return mPM.getAllPermissionGroups(flags);
1556 } catch (RemoteException e) {
1557 throw new RuntimeException("Package manager has died", e);
1558 }
1559 }
1560
1561 @Override
1562 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1563 throws NameNotFoundException {
1564 try {
1565 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1566 if (ai != null) {
1567 return ai;
1568 }
1569 } catch (RemoteException e) {
1570 throw new RuntimeException("Package manager has died", e);
1571 }
1572
1573 throw new NameNotFoundException(packageName);
1574 }
1575
1576 @Override
1577 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1578 throws NameNotFoundException {
1579 try {
1580 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1581 if (ai != null) {
1582 return ai;
1583 }
1584 } catch (RemoteException e) {
1585 throw new RuntimeException("Package manager has died", e);
1586 }
1587
1588 throw new NameNotFoundException(className.toString());
1589 }
1590
1591 @Override
1592 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1593 throws NameNotFoundException {
1594 try {
1595 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1596 if (ai != null) {
1597 return ai;
1598 }
1599 } catch (RemoteException e) {
1600 throw new RuntimeException("Package manager has died", e);
1601 }
1602
1603 throw new NameNotFoundException(className.toString());
1604 }
1605
1606 @Override
1607 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1608 throws NameNotFoundException {
1609 try {
1610 ServiceInfo si = mPM.getServiceInfo(className, flags);
1611 if (si != null) {
1612 return si;
1613 }
1614 } catch (RemoteException e) {
1615 throw new RuntimeException("Package manager has died", e);
1616 }
1617
1618 throw new NameNotFoundException(className.toString());
1619 }
1620
1621 @Override
1622 public String[] getSystemSharedLibraryNames() {
1623 try {
1624 return mPM.getSystemSharedLibraryNames();
1625 } catch (RemoteException e) {
1626 throw new RuntimeException("Package manager has died", e);
1627 }
1628 }
1629
1630 @Override
1631 public int checkPermission(String permName, String pkgName) {
1632 try {
1633 return mPM.checkPermission(permName, pkgName);
1634 } catch (RemoteException e) {
1635 throw new RuntimeException("Package manager has died", e);
1636 }
1637 }
1638
1639 @Override
1640 public boolean addPermission(PermissionInfo info) {
1641 try {
1642 return mPM.addPermission(info);
1643 } catch (RemoteException e) {
1644 throw new RuntimeException("Package manager has died", e);
1645 }
1646 }
1647
1648 @Override
1649 public void removePermission(String name) {
1650 try {
1651 mPM.removePermission(name);
1652 } catch (RemoteException e) {
1653 throw new RuntimeException("Package manager has died", e);
1654 }
1655 }
1656
1657 @Override
1658 public int checkSignatures(String pkg1, String pkg2) {
1659 try {
1660 return mPM.checkSignatures(pkg1, pkg2);
1661 } catch (RemoteException e) {
1662 throw new RuntimeException("Package manager has died", e);
1663 }
1664 }
1665
1666 @Override
1667 public String[] getPackagesForUid(int uid) {
1668 try {
1669 return mPM.getPackagesForUid(uid);
1670 } catch (RemoteException e) {
1671 throw new RuntimeException("Package manager has died", e);
1672 }
1673 }
1674
1675 @Override
1676 public String getNameForUid(int uid) {
1677 try {
1678 return mPM.getNameForUid(uid);
1679 } catch (RemoteException e) {
1680 throw new RuntimeException("Package manager has died", e);
1681 }
1682 }
1683
1684 @Override
1685 public int getUidForSharedUser(String sharedUserName)
1686 throws NameNotFoundException {
1687 try {
1688 int uid = mPM.getUidForSharedUser(sharedUserName);
1689 if(uid != -1) {
1690 return uid;
1691 }
1692 } catch (RemoteException e) {
1693 throw new RuntimeException("Package manager has died", e);
1694 }
1695 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1696 }
1697
1698 @Override
1699 public List<PackageInfo> getInstalledPackages(int flags) {
1700 try {
1701 return mPM.getInstalledPackages(flags);
1702 } catch (RemoteException e) {
1703 throw new RuntimeException("Package manager has died", e);
1704 }
1705 }
1706
1707 @Override
1708 public List<ApplicationInfo> getInstalledApplications(int flags) {
1709 try {
1710 return mPM.getInstalledApplications(flags);
1711 } catch (RemoteException e) {
1712 throw new RuntimeException("Package manager has died", e);
1713 }
1714 }
1715
1716 @Override
1717 public ResolveInfo resolveActivity(Intent intent, int flags) {
1718 try {
1719 return mPM.resolveIntent(
1720 intent,
1721 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1722 flags);
1723 } catch (RemoteException e) {
1724 throw new RuntimeException("Package manager has died", e);
1725 }
1726 }
1727
1728 @Override
1729 public List<ResolveInfo> queryIntentActivities(Intent intent,
1730 int flags) {
1731 try {
1732 return mPM.queryIntentActivities(
1733 intent,
1734 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1735 flags);
1736 } catch (RemoteException e) {
1737 throw new RuntimeException("Package manager has died", e);
1738 }
1739 }
1740
1741 @Override
1742 public List<ResolveInfo> queryIntentActivityOptions(
1743 ComponentName caller, Intent[] specifics, Intent intent,
1744 int flags) {
1745 final ContentResolver resolver = mContext.getContentResolver();
1746
1747 String[] specificTypes = null;
1748 if (specifics != null) {
1749 final int N = specifics.length;
1750 for (int i=0; i<N; i++) {
1751 Intent sp = specifics[i];
1752 if (sp != null) {
1753 String t = sp.resolveTypeIfNeeded(resolver);
1754 if (t != null) {
1755 if (specificTypes == null) {
1756 specificTypes = new String[N];
1757 }
1758 specificTypes[i] = t;
1759 }
1760 }
1761 }
1762 }
1763
1764 try {
1765 return mPM.queryIntentActivityOptions(caller, specifics,
1766 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
1767 flags);
1768 } catch (RemoteException e) {
1769 throw new RuntimeException("Package manager has died", e);
1770 }
1771 }
1772
1773 @Override
1774 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
1775 try {
1776 return mPM.queryIntentReceivers(
1777 intent,
1778 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1779 flags);
1780 } catch (RemoteException e) {
1781 throw new RuntimeException("Package manager has died", e);
1782 }
1783 }
1784
1785 @Override
1786 public ResolveInfo resolveService(Intent intent, int flags) {
1787 try {
1788 return mPM.resolveService(
1789 intent,
1790 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1791 flags);
1792 } catch (RemoteException e) {
1793 throw new RuntimeException("Package manager has died", e);
1794 }
1795 }
1796
1797 @Override
1798 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
1799 try {
1800 return mPM.queryIntentServices(
1801 intent,
1802 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1803 flags);
1804 } catch (RemoteException e) {
1805 throw new RuntimeException("Package manager has died", e);
1806 }
1807 }
1808
1809 @Override
1810 public ProviderInfo resolveContentProvider(String name,
1811 int flags) {
1812 try {
1813 return mPM.resolveContentProvider(name, flags);
1814 } catch (RemoteException e) {
1815 throw new RuntimeException("Package manager has died", e);
1816 }
1817 }
1818
1819 @Override
1820 public List<ProviderInfo> queryContentProviders(String processName,
1821 int uid, int flags) {
1822 try {
1823 return mPM.queryContentProviders(processName, uid, flags);
1824 } catch (RemoteException e) {
1825 throw new RuntimeException("Package manager has died", e);
1826 }
1827 }
1828
1829 @Override
1830 public InstrumentationInfo getInstrumentationInfo(
1831 ComponentName className, int flags)
1832 throws NameNotFoundException {
1833 try {
1834 InstrumentationInfo ii = mPM.getInstrumentationInfo(
1835 className, flags);
1836 if (ii != null) {
1837 return ii;
1838 }
1839 } catch (RemoteException e) {
1840 throw new RuntimeException("Package manager has died", e);
1841 }
1842
1843 throw new NameNotFoundException(className.toString());
1844 }
1845
1846 @Override
1847 public List<InstrumentationInfo> queryInstrumentation(
1848 String targetPackage, int flags) {
1849 try {
1850 return mPM.queryInstrumentation(targetPackage, flags);
1851 } catch (RemoteException e) {
1852 throw new RuntimeException("Package manager has died", e);
1853 }
1854 }
1855
1856 @Override public Drawable getDrawable(String packageName, int resid,
1857 ApplicationInfo appInfo) {
1858 ResourceName name = new ResourceName(packageName, resid);
1859 Drawable dr = getCachedIcon(name);
1860 if (dr != null) {
1861 return dr;
1862 }
1863 if (appInfo == null) {
1864 try {
1865 appInfo = getApplicationInfo(packageName, 0);
1866 } catch (NameNotFoundException e) {
1867 return null;
1868 }
1869 }
1870 try {
1871 Resources r = getResourcesForApplication(appInfo);
1872 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07001873 if (false) {
1874 RuntimeException e = new RuntimeException("here");
1875 e.fillInStackTrace();
1876 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
1877 + " from package " + packageName
1878 + ": app scale=" + r.getCompatibilityInfo().applicationScale
1879 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
1880 e);
1881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
1883 + Integer.toHexString(resid) + " from " + r
1884 + ": " + dr);
1885 putCachedIcon(name, dr);
1886 return dr;
1887 } catch (NameNotFoundException e) {
1888 Log.w("PackageManager", "Failure retrieving resources for"
1889 + appInfo.packageName);
1890 } catch (RuntimeException e) {
1891 // If an exception was thrown, fall through to return
1892 // default icon.
1893 Log.w("PackageManager", "Failure retrieving icon 0x"
1894 + Integer.toHexString(resid) + " in package "
1895 + packageName, e);
1896 }
1897 return null;
1898 }
1899
1900 @Override public Drawable getActivityIcon(ComponentName activityName)
1901 throws NameNotFoundException {
1902 return getActivityInfo(activityName, 0).loadIcon(this);
1903 }
1904
1905 @Override public Drawable getActivityIcon(Intent intent)
1906 throws NameNotFoundException {
1907 if (intent.getComponent() != null) {
1908 return getActivityIcon(intent.getComponent());
1909 }
1910
1911 ResolveInfo info = resolveActivity(
1912 intent, PackageManager.MATCH_DEFAULT_ONLY);
1913 if (info != null) {
1914 return info.activityInfo.loadIcon(this);
1915 }
1916
1917 throw new NameNotFoundException(intent.toURI());
1918 }
1919
1920 @Override public Drawable getDefaultActivityIcon() {
1921 return Resources.getSystem().getDrawable(
1922 com.android.internal.R.drawable.sym_def_app_icon);
1923 }
1924
1925 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
1926 final int icon = info.icon;
1927 if (icon != 0) {
1928 ResourceName name = new ResourceName(info, icon);
1929 Drawable dr = getCachedIcon(name);
1930 if (dr != null) {
1931 return dr;
1932 }
1933 try {
1934 Resources r = getResourcesForApplication(info);
1935 dr = r.getDrawable(icon);
1936 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
1937 + Integer.toHexString(icon) + " from " + r
1938 + ": " + dr);
1939 putCachedIcon(name, dr);
1940 return dr;
1941 } catch (NameNotFoundException e) {
1942 Log.w("PackageManager", "Failure retrieving resources for"
1943 + info.packageName);
1944 } catch (RuntimeException e) {
1945 // If an exception was thrown, fall through to return
1946 // default icon.
1947 Log.w("PackageManager", "Failure retrieving app icon", e);
1948 }
1949 }
1950 return getDefaultActivityIcon();
1951 }
1952
1953 @Override public Drawable getApplicationIcon(String packageName)
1954 throws NameNotFoundException {
1955 return getApplicationIcon(getApplicationInfo(packageName, 0));
1956 }
1957
1958 @Override public Resources getResourcesForActivity(
1959 ComponentName activityName) throws NameNotFoundException {
1960 return getResourcesForApplication(
1961 getActivityInfo(activityName, 0).applicationInfo);
1962 }
1963
1964 @Override public Resources getResourcesForApplication(
1965 ApplicationInfo app) throws NameNotFoundException {
1966 if (app.packageName.equals("system")) {
1967 return mContext.mMainThread.getSystemContext().getResources();
1968 }
1969 Resources r = mContext.mMainThread.getTopLevelResources(
1970 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07001971 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 if (r != null) {
1973 return r;
1974 }
1975 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
1976 }
1977
1978 @Override public Resources getResourcesForApplication(
1979 String appPackageName) throws NameNotFoundException {
1980 return getResourcesForApplication(
1981 getApplicationInfo(appPackageName, 0));
1982 }
1983
1984 int mCachedSafeMode = -1;
1985 @Override public boolean isSafeMode() {
1986 try {
1987 if (mCachedSafeMode < 0) {
1988 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
1989 }
1990 return mCachedSafeMode != 0;
1991 } catch (RemoteException e) {
1992 throw new RuntimeException("Package manager has died", e);
1993 }
1994 }
1995
1996 static void configurationChanged() {
1997 synchronized (sSync) {
1998 sIconCache.clear();
1999 sStringCache.clear();
2000 }
2001 }
2002
2003 ApplicationPackageManager(ApplicationContext context,
2004 IPackageManager pm) {
2005 mContext = context;
2006 mPM = pm;
2007 }
2008
2009 private Drawable getCachedIcon(ResourceName name) {
2010 synchronized (sSync) {
2011 WeakReference<Drawable> wr = sIconCache.get(name);
2012 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2013 + name + ": " + wr);
2014 if (wr != null) { // we have the activity
2015 Drawable dr = wr.get();
2016 if (dr != null) {
2017 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2018 + name + ": " + dr);
2019 return dr;
2020 }
2021 // our entry has been purged
2022 sIconCache.remove(name);
2023 }
2024 }
2025 return null;
2026 }
2027
2028 private void establishPackageRemovedReceiver() {
2029 // mContext.registerReceiverInternal() winds up acquiring the
2030 // main ActivityManagerService.this lock. If we hold our usual
2031 // sSync global lock at the same time, we impose a required ordering
2032 // on those two locks, which is not good for deadlock prevention.
2033 // Use a dedicated lock around initialization of
2034 // sPackageRemovedReceiver to avoid this.
2035 synchronized (sPackageRemovedSync) {
2036 if (sPackageRemovedReceiver == null) {
2037 sPackageRemovedReceiver = new PackageRemovedReceiver();
2038 IntentFilter filter = new IntentFilter(
2039 Intent.ACTION_PACKAGE_REMOVED);
2040 filter.addDataScheme("package");
2041 mContext.registerReceiverInternal(sPackageRemovedReceiver,
2042 filter, null, null, null);
2043 }
2044 }
2045 }
2046
2047 private void putCachedIcon(ResourceName name, Drawable dr) {
2048 establishPackageRemovedReceiver();
2049
2050 synchronized (sSync) {
2051 sIconCache.put(name, new WeakReference<Drawable>(dr));
2052 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2053 + name + ": " + dr);
2054 }
2055 }
2056
2057 private static final class PackageRemovedReceiver extends BroadcastReceiver {
2058 @Override
2059 public void onReceive(Context context, Intent intent) {
2060 Uri data = intent.getData();
2061 String ssp;
2062 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
2063 boolean needCleanup = false;
2064 synchronized (sSync) {
2065 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2066 while (it.hasNext()) {
2067 ResourceName nm = it.next();
2068 if (nm.packageName.equals(ssp)) {
2069 //Log.i(TAG, "Removing cached drawable for " + nm);
2070 it.remove();
2071 needCleanup = true;
2072 }
2073 }
2074 it = sStringCache.keySet().iterator();
2075 while (it.hasNext()) {
2076 ResourceName nm = it.next();
2077 if (nm.packageName.equals(ssp)) {
2078 //Log.i(TAG, "Removing cached string for " + nm);
2079 it.remove();
2080 needCleanup = true;
2081 }
2082 }
2083 }
2084 if (needCleanup || ActivityThread.currentActivityThread().hasPackageInfo(ssp)) {
2085 ActivityThread.currentActivityThread().scheduleGcIdler();
2086 }
2087 }
2088 }
2089 }
2090
2091 private static final class ResourceName {
2092 final String packageName;
2093 final int iconId;
2094
2095 ResourceName(String _packageName, int _iconId) {
2096 packageName = _packageName;
2097 iconId = _iconId;
2098 }
2099
2100 ResourceName(ApplicationInfo aInfo, int _iconId) {
2101 this(aInfo.packageName, _iconId);
2102 }
2103
2104 ResourceName(ComponentInfo cInfo, int _iconId) {
2105 this(cInfo.applicationInfo.packageName, _iconId);
2106 }
2107
2108 ResourceName(ResolveInfo rInfo, int _iconId) {
2109 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2110 }
2111
2112 @Override
2113 public boolean equals(Object o) {
2114 if (this == o) return true;
2115 if (o == null || getClass() != o.getClass()) return false;
2116
2117 ResourceName that = (ResourceName) o;
2118
2119 if (iconId != that.iconId) return false;
2120 return !(packageName != null ?
2121 !packageName.equals(that.packageName) : that.packageName != null);
2122
2123 }
2124
2125 @Override
2126 public int hashCode() {
2127 int result;
2128 result = packageName.hashCode();
2129 result = 31 * result + iconId;
2130 return result;
2131 }
2132
2133 @Override
2134 public String toString() {
2135 return "{ResourceName " + packageName + " / " + iconId + "}";
2136 }
2137 }
2138
2139 private CharSequence getCachedString(ResourceName name) {
2140 synchronized (sSync) {
2141 WeakReference<CharSequence> wr = sStringCache.get(name);
2142 if (wr != null) { // we have the activity
2143 CharSequence cs = wr.get();
2144 if (cs != null) {
2145 return cs;
2146 }
2147 // our entry has been purged
2148 sStringCache.remove(name);
2149 }
2150 }
2151 return null;
2152 }
2153
2154 private void putCachedString(ResourceName name, CharSequence cs) {
2155 establishPackageRemovedReceiver();
2156
2157 synchronized (sSync) {
2158 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2159 }
2160 }
2161
2162 private CharSequence getLabel(ResourceName name, ApplicationInfo app, int id) {
2163 CharSequence cs = getCachedString(name);
2164 if (cs != null) {
2165 return cs;
2166 }
2167 try {
2168 Resources r = getResourcesForApplication(app);
2169 cs = r.getText(id);
2170 putCachedString(name, cs);
2171 } catch (NameNotFoundException e) {
2172 Log.w("PackageManager", "Failure retrieving resources for"
2173 + app.packageName);
2174 } catch (RuntimeException e) {
2175 // If an exception was thrown, fall through to return null
2176 Log.w("ApplicationInfo", "Failure retrieving activity name", e);
2177 }
2178 return cs;
2179 }
2180
2181 @Override
2182 public CharSequence getText(String packageName, int resid,
2183 ApplicationInfo appInfo) {
2184 ResourceName name = new ResourceName(packageName, resid);
2185 CharSequence text = getCachedString(name);
2186 if (text != null) {
2187 return text;
2188 }
2189 if (appInfo == null) {
2190 try {
2191 appInfo = getApplicationInfo(packageName, 0);
2192 } catch (NameNotFoundException e) {
2193 return null;
2194 }
2195 }
2196 try {
2197 Resources r = getResourcesForApplication(appInfo);
2198 text = r.getText(resid);
2199 putCachedString(name, text);
2200 return text;
2201 } catch (NameNotFoundException e) {
2202 Log.w("PackageManager", "Failure retrieving resources for"
2203 + appInfo.packageName);
2204 } catch (RuntimeException e) {
2205 // If an exception was thrown, fall through to return
2206 // default icon.
2207 Log.w("PackageManager", "Failure retrieving text 0x"
2208 + Integer.toHexString(resid) + " in package "
2209 + packageName, e);
2210 }
2211 return null;
2212 }
2213
2214 @Override
2215 public XmlResourceParser getXml(String packageName, int resid,
2216 ApplicationInfo appInfo) {
2217 if (appInfo == null) {
2218 try {
2219 appInfo = getApplicationInfo(packageName, 0);
2220 } catch (NameNotFoundException e) {
2221 return null;
2222 }
2223 }
2224 try {
2225 Resources r = getResourcesForApplication(appInfo);
2226 return r.getXml(resid);
2227 } catch (RuntimeException e) {
2228 // If an exception was thrown, fall through to return
2229 // default icon.
2230 Log.w("PackageManager", "Failure retrieving xml 0x"
2231 + Integer.toHexString(resid) + " in package "
2232 + packageName, e);
2233 } catch (NameNotFoundException e) {
2234 Log.w("PackageManager", "Failure retrieving resources for"
2235 + appInfo.packageName);
2236 }
2237 return null;
2238 }
2239
2240 @Override
2241 public CharSequence getApplicationLabel(ApplicationInfo info) {
2242 if (info.nonLocalizedLabel != null) {
2243 return info.nonLocalizedLabel;
2244 }
2245 final int id = info.labelRes;
2246 if (id != 0) {
2247 CharSequence cs = getLabel(new ResourceName(info, id), info, id);
2248 if (cs != null) {
2249 return cs;
2250 }
2251 }
2252 return info.packageName;
2253 }
2254
2255 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002256 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2257 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002259 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 } catch (RemoteException e) {
2261 // Should never happen!
2262 }
2263 }
2264
2265 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002266 public String getInstallerPackageName(String packageName) {
2267 try {
2268 return mPM.getInstallerPackageName(packageName);
2269 } catch (RemoteException e) {
2270 // Should never happen!
2271 }
2272 return null;
2273 }
2274
2275 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2277 try {
2278 mPM.deletePackage(packageName, observer, flags);
2279 } catch (RemoteException e) {
2280 // Should never happen!
2281 }
2282 }
2283 @Override
2284 public void clearApplicationUserData(String packageName,
2285 IPackageDataObserver observer) {
2286 try {
2287 mPM.clearApplicationUserData(packageName, observer);
2288 } catch (RemoteException e) {
2289 // Should never happen!
2290 }
2291 }
2292 @Override
2293 public void deleteApplicationCacheFiles(String packageName,
2294 IPackageDataObserver observer) {
2295 try {
2296 mPM.deleteApplicationCacheFiles(packageName, observer);
2297 } catch (RemoteException e) {
2298 // Should never happen!
2299 }
2300 }
2301 @Override
2302 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2303 try {
2304 mPM.freeStorageAndNotify(idealStorageSize, observer);
2305 } catch (RemoteException e) {
2306 // Should never happen!
2307 }
2308 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002311 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002313 mPM.freeStorage(freeStorageSize, pi);
2314 } catch (RemoteException e) {
2315 // Should never happen!
2316 }
2317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318
2319 @Override
2320 public void getPackageSizeInfo(String packageName,
2321 IPackageStatsObserver observer) {
2322 try {
2323 mPM.getPackageSizeInfo(packageName, observer);
2324 } catch (RemoteException e) {
2325 // Should never happen!
2326 }
2327 }
2328 @Override
2329 public void addPackageToPreferred(String packageName) {
2330 try {
2331 mPM.addPackageToPreferred(packageName);
2332 } catch (RemoteException e) {
2333 // Should never happen!
2334 }
2335 }
2336
2337 @Override
2338 public void removePackageFromPreferred(String packageName) {
2339 try {
2340 mPM.removePackageFromPreferred(packageName);
2341 } catch (RemoteException e) {
2342 // Should never happen!
2343 }
2344 }
2345
2346 @Override
2347 public List<PackageInfo> getPreferredPackages(int flags) {
2348 try {
2349 return mPM.getPreferredPackages(flags);
2350 } catch (RemoteException e) {
2351 // Should never happen!
2352 }
2353 return new ArrayList<PackageInfo>();
2354 }
2355
2356 @Override
2357 public void addPreferredActivity(IntentFilter filter,
2358 int match, ComponentName[] set, ComponentName activity) {
2359 try {
2360 mPM.addPreferredActivity(filter, match, set, activity);
2361 } catch (RemoteException e) {
2362 // Should never happen!
2363 }
2364 }
2365
2366 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002367 public void replacePreferredActivity(IntentFilter filter,
2368 int match, ComponentName[] set, ComponentName activity) {
2369 try {
2370 mPM.replacePreferredActivity(filter, match, set, activity);
2371 } catch (RemoteException e) {
2372 // Should never happen!
2373 }
2374 }
2375
2376 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 public void clearPackagePreferredActivities(String packageName) {
2378 try {
2379 mPM.clearPackagePreferredActivities(packageName);
2380 } catch (RemoteException e) {
2381 // Should never happen!
2382 }
2383 }
2384
2385 @Override
2386 public int getPreferredActivities(List<IntentFilter> outFilters,
2387 List<ComponentName> outActivities, String packageName) {
2388 try {
2389 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2390 } catch (RemoteException e) {
2391 // Should never happen!
2392 }
2393 return 0;
2394 }
2395
2396 @Override
2397 public void setComponentEnabledSetting(ComponentName componentName,
2398 int newState, int flags) {
2399 try {
2400 mPM.setComponentEnabledSetting(componentName, newState, flags);
2401 } catch (RemoteException e) {
2402 // Should never happen!
2403 }
2404 }
2405
2406 @Override
2407 public int getComponentEnabledSetting(ComponentName componentName) {
2408 try {
2409 return mPM.getComponentEnabledSetting(componentName);
2410 } catch (RemoteException e) {
2411 // Should never happen!
2412 }
2413 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2414 }
2415
2416 @Override
2417 public void setApplicationEnabledSetting(String packageName,
2418 int newState, int flags) {
2419 try {
2420 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2421 } catch (RemoteException e) {
2422 // Should never happen!
2423 }
2424 }
2425
2426 @Override
2427 public int getApplicationEnabledSetting(String packageName) {
2428 try {
2429 return mPM.getApplicationEnabledSetting(packageName);
2430 } catch (RemoteException e) {
2431 // Should never happen!
2432 }
2433 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2434 }
2435
2436 private final ApplicationContext mContext;
2437 private final IPackageManager mPM;
2438
2439 private static final Object sSync = new Object();
2440 private static final Object sPackageRemovedSync = new Object();
2441 private static BroadcastReceiver sPackageRemovedReceiver;
2442 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2443 = new HashMap<ResourceName, WeakReference<Drawable> >();
2444 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2445 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2446 }
2447
2448 // ----------------------------------------------------------------------
2449 // ----------------------------------------------------------------------
2450 // ----------------------------------------------------------------------
2451
2452 private static final class SharedPreferencesImpl implements SharedPreferences {
2453
2454 private final File mFile;
2455 private final File mBackupFile;
2456 private final int mMode;
2457 private Map mMap;
2458 private final FileStatus mFileStatus = new FileStatus();
2459 private long mTimestamp;
2460
The Android Open Source Project10592532009-03-18 17:39:46 -07002461 private static final Object mContent = new Object();
2462 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463
2464 SharedPreferencesImpl(
2465 File file, int mode, Map initialContents) {
2466 mFile = file;
2467 mBackupFile = makeBackupFile(file);
2468 mMode = mode;
2469 mMap = initialContents != null ? initialContents : new HashMap();
2470 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2471 mTimestamp = mFileStatus.mtime;
2472 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002473 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 }
2475
2476 public boolean hasFileChanged() {
2477 synchronized (this) {
2478 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2479 return true;
2480 }
2481 return mTimestamp != mFileStatus.mtime;
2482 }
2483 }
2484
2485 public void replace(Map newContents) {
2486 if (newContents != null) {
2487 synchronized (this) {
2488 mMap = newContents;
2489 }
2490 }
2491 }
2492
2493 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2494 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002495 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002496 }
2497 }
2498
2499 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2500 synchronized(this) {
2501 mListeners.remove(listener);
2502 }
2503 }
2504
2505 public Map<String, ?> getAll() {
2506 synchronized(this) {
2507 //noinspection unchecked
2508 return new HashMap(mMap);
2509 }
2510 }
2511
2512 public String getString(String key, String defValue) {
2513 synchronized (this) {
2514 String v = (String)mMap.get(key);
2515 return v != null ? v : defValue;
2516 }
2517 }
2518
2519 public int getInt(String key, int defValue) {
2520 synchronized (this) {
2521 Integer v = (Integer)mMap.get(key);
2522 return v != null ? v : defValue;
2523 }
2524 }
2525 public long getLong(String key, long defValue) {
2526 synchronized (this) {
2527 Long v = (Long) mMap.get(key);
2528 return v != null ? v : defValue;
2529 }
2530 }
2531 public float getFloat(String key, float defValue) {
2532 synchronized (this) {
2533 Float v = (Float)mMap.get(key);
2534 return v != null ? v : defValue;
2535 }
2536 }
2537 public boolean getBoolean(String key, boolean defValue) {
2538 synchronized (this) {
2539 Boolean v = (Boolean)mMap.get(key);
2540 return v != null ? v : defValue;
2541 }
2542 }
2543
2544 public boolean contains(String key) {
2545 synchronized (this) {
2546 return mMap.containsKey(key);
2547 }
2548 }
2549
2550 public final class EditorImpl implements Editor {
2551 private final Map<String, Object> mModified = Maps.newHashMap();
2552 private boolean mClear = false;
2553
2554 public Editor putString(String key, String value) {
2555 synchronized (this) {
2556 mModified.put(key, value);
2557 return this;
2558 }
2559 }
2560 public Editor putInt(String key, int value) {
2561 synchronized (this) {
2562 mModified.put(key, value);
2563 return this;
2564 }
2565 }
2566 public Editor putLong(String key, long value) {
2567 synchronized (this) {
2568 mModified.put(key, value);
2569 return this;
2570 }
2571 }
2572 public Editor putFloat(String key, float value) {
2573 synchronized (this) {
2574 mModified.put(key, value);
2575 return this;
2576 }
2577 }
2578 public Editor putBoolean(String key, boolean value) {
2579 synchronized (this) {
2580 mModified.put(key, value);
2581 return this;
2582 }
2583 }
2584
2585 public Editor remove(String key) {
2586 synchronized (this) {
2587 mModified.put(key, this);
2588 return this;
2589 }
2590 }
2591
2592 public Editor clear() {
2593 synchronized (this) {
2594 mClear = true;
2595 return this;
2596 }
2597 }
2598
2599 public boolean commit() {
2600 boolean returnValue;
2601
2602 boolean hasListeners;
2603 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002604 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605
2606 synchronized (SharedPreferencesImpl.this) {
2607 hasListeners = mListeners.size() > 0;
2608 if (hasListeners) {
2609 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002610 listeners =
2611 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 }
2613
2614 synchronized (this) {
2615 if (mClear) {
2616 mMap.clear();
2617 mClear = false;
2618 }
2619
The Android Open Source Project10592532009-03-18 17:39:46 -07002620 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 String k = e.getKey();
2622 Object v = e.getValue();
2623 if (v == this) {
2624 mMap.remove(k);
2625 } else {
2626 mMap.put(k, v);
2627 }
2628
2629 if (hasListeners) {
2630 keysModified.add(k);
2631 }
2632 }
2633
2634 mModified.clear();
2635 }
2636
2637 returnValue = writeFileLocked();
2638 }
2639
2640 if (hasListeners) {
2641 for (int i = keysModified.size() - 1; i >= 0; i--) {
2642 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002643 for (OnSharedPreferenceChangeListener listener : listeners) {
2644 if (listener != null) {
2645 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 }
2648 }
2649 }
2650
2651 return returnValue;
2652 }
2653 }
2654
2655 public Editor edit() {
2656 return new EditorImpl();
2657 }
2658
2659 private FileOutputStream createFileOutputStream(File file) {
2660 FileOutputStream str = null;
2661 try {
2662 str = new FileOutputStream(file);
2663 } catch (FileNotFoundException e) {
2664 File parent = file.getParentFile();
2665 if (!parent.mkdir()) {
2666 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2667 return null;
2668 }
2669 FileUtils.setPermissions(
2670 parent.getPath(),
2671 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2672 -1, -1);
2673 try {
2674 str = new FileOutputStream(file);
2675 } catch (FileNotFoundException e2) {
2676 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2677 }
2678 }
2679 return str;
2680 }
2681
2682 private boolean writeFileLocked() {
2683 // Rename the current file so it may be used as a backup during the next read
2684 if (mFile.exists()) {
2685 if (!mFile.renameTo(mBackupFile)) {
2686 Log.e(TAG, "Couldn't rename file " + mFile + " to backup file " + mBackupFile);
2687 }
2688 }
2689
2690 // Attempt to write the file, delete the backup and return true as atomically as
2691 // possible. If any exception occurs, delete the new file; next time we will restore
2692 // from the backup.
2693 try {
2694 FileOutputStream str = createFileOutputStream(mFile);
2695 if (str == null) {
2696 return false;
2697 }
2698 XmlUtils.writeMapXml(mMap, str);
2699 str.close();
2700 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2701 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2702 mTimestamp = mFileStatus.mtime;
2703 }
2704
Dianne Hackborn51bf0772009-03-24 19:11:41 -07002705 // Writing was successful, delete the backup file if there is one.
2706 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002707 return true;
2708 } catch (XmlPullParserException e) {
2709 Log.w(TAG, "writeFileLocked: Got exception:", e);
2710 } catch (IOException e) {
2711 Log.w(TAG, "writeFileLocked: Got exception:", e);
2712 }
2713 // Clean up an unsuccessfully written file
2714 if (mFile.exists()) {
2715 if (!mFile.delete()) {
2716 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2717 }
2718 }
2719 return false;
2720 }
2721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722}