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