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