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