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