ContextImpl.java revision 5fd2169eabd77e6bfafaf456e58051a3bafb2bca
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; 20 21import android.content.BroadcastReceiver; 22import android.content.ComponentName; 23import android.content.ContentResolver; 24import android.content.Context; 25import android.content.ContextWrapper; 26import android.content.IContentProvider; 27import android.content.Intent; 28import android.content.IntentFilter; 29import android.content.IIntentReceiver; 30import android.content.IntentSender; 31import android.content.ReceiverCallNotAllowedException; 32import android.content.ServiceConnection; 33import android.content.SharedPreferences; 34import android.content.pm.ApplicationInfo; 35import android.content.pm.IPackageManager; 36import android.content.pm.PackageManager; 37import android.content.res.AssetManager; 38import android.content.res.CompatibilityInfo; 39import android.content.res.Resources; 40import android.database.DatabaseErrorHandler; 41import android.database.sqlite.SQLiteDatabase; 42import android.database.sqlite.SQLiteDatabase.CursorFactory; 43import android.graphics.Bitmap; 44import android.graphics.drawable.Drawable; 45import android.hardware.SensorManager; 46import android.hardware.usb.IUsbManager; 47import android.hardware.usb.UsbManager; 48import android.location.CountryDetector; 49import android.location.ICountryDetector; 50import android.location.ILocationManager; 51import android.location.LocationManager; 52import android.media.AudioManager; 53import android.net.ConnectivityManager; 54import android.net.IConnectivityManager; 55import android.net.ThrottleManager; 56import android.net.IThrottleManager; 57import android.net.Uri; 58import android.net.wifi.IWifiManager; 59import android.net.wifi.WifiManager; 60import android.nfc.NfcManager; 61import android.os.Binder; 62import android.os.Build; 63import android.os.Bundle; 64import android.os.DropBoxManager; 65import android.os.Environment; 66import android.os.FileUtils; 67import android.os.Handler; 68import android.os.IBinder; 69import android.os.IPowerManager; 70import android.os.Looper; 71import android.os.PowerManager; 72import android.os.Process; 73import android.os.RemoteException; 74import android.os.ServiceManager; 75import android.os.Vibrator; 76import android.os.storage.StorageManager; 77import android.telephony.TelephonyManager; 78import android.content.ClipboardManager; 79import android.util.AndroidRuntimeException; 80import android.util.Log; 81import android.view.ContextThemeWrapper; 82import android.view.Display; 83import android.view.WindowManagerImpl; 84import android.view.accessibility.AccessibilityManager; 85import android.view.inputmethod.InputMethodManager; 86import android.accounts.AccountManager; 87import android.accounts.IAccountManager; 88import android.app.admin.DevicePolicyManager; 89import com.android.internal.os.IDropBoxManagerService; 90 91import java.io.File; 92import java.io.FileInputStream; 93import java.io.FileNotFoundException; 94import java.io.FileOutputStream; 95import java.io.IOException; 96import java.io.InputStream; 97import java.util.ArrayList; 98import java.util.HashMap; 99 100class ReceiverRestrictedContext extends ContextWrapper { 101 ReceiverRestrictedContext(Context base) { 102 super(base); 103 } 104 105 @Override 106 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 107 return registerReceiver(receiver, filter, null, null); 108 } 109 110 @Override 111 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 112 String broadcastPermission, Handler scheduler) { 113 throw new ReceiverCallNotAllowedException( 114 "IntentReceiver components are not allowed to register to receive intents"); 115 //ex.fillInStackTrace(); 116 //Log.e("IntentReceiver", ex.getMessage(), ex); 117 //return mContext.registerReceiver(receiver, filter, broadcastPermission, 118 // scheduler); 119 } 120 121 @Override 122 public boolean bindService(Intent service, ServiceConnection conn, int flags) { 123 throw new ReceiverCallNotAllowedException( 124 "IntentReceiver components are not allowed to bind to services"); 125 //ex.fillInStackTrace(); 126 //Log.e("IntentReceiver", ex.getMessage(), ex); 127 //return mContext.bindService(service, interfaceName, conn, flags); 128 } 129} 130 131/** 132 * Common implementation of Context API, which provides the base 133 * context object for Activity and other application components. 134 */ 135class ContextImpl extends Context { 136 private final static String TAG = "ApplicationContext"; 137 private final static boolean DEBUG = false; 138 139 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs = 140 new HashMap<String, SharedPreferencesImpl>(); 141 142 /*package*/ LoadedApk mPackageInfo; 143 private Resources mResources; 144 /*package*/ ActivityThread mMainThread; 145 private Context mOuterContext; 146 private IBinder mActivityToken = null; 147 private ApplicationContentResolver mContentResolver; 148 private int mThemeResource = 0; 149 private Resources.Theme mTheme = null; 150 private PackageManager mPackageManager; 151 private Context mReceiverRestrictedContext = null; 152 private boolean mRestricted; 153 154 private final Object mSync = new Object(); 155 156 private File mDatabasesDir; 157 private File mPreferencesDir; 158 private File mFilesDir; 159 private File mCacheDir; 160 private File mObbDir; 161 private File mExternalFilesDir; 162 private File mExternalCacheDir; 163 164 private static final String[] EMPTY_FILE_LIST = {}; 165 166 /** 167 * Override this class when the system service constructor needs a 168 * ContextImpl. Else, use StaticServiceFetcher below. 169 */ 170 /*package*/ static class ServiceFetcher { 171 int mContextCacheIndex = -1; 172 173 /** 174 * Main entrypoint; only override if you don't need caching. 175 */ 176 public Object getService(ContextImpl ctx) { 177 ArrayList<Object> cache = ctx.mServiceCache; 178 Object service; 179 synchronized (cache) { 180 if (cache.size() == 0) { 181 // Initialize the cache vector on first access. 182 // At this point sNextPerContextServiceCacheIndex 183 // is the number of potential services that are 184 // cached per-Context. 185 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) { 186 cache.add(null); 187 } 188 } else { 189 service = cache.get(mContextCacheIndex); 190 if (service != null) { 191 return service; 192 } 193 } 194 service = createService(ctx); 195 cache.set(mContextCacheIndex, service); 196 return service; 197 } 198 } 199 200 /** 201 * Override this to create a new per-Context instance of the 202 * service. getService() will handle locking and caching. 203 */ 204 public Object createService(ContextImpl ctx) { 205 throw new RuntimeException("Not implemented"); 206 } 207 } 208 209 /** 210 * Override this class for services to be cached process-wide. 211 */ 212 abstract static class StaticServiceFetcher extends ServiceFetcher { 213 private Object mCachedInstance; 214 215 @Override 216 public final Object getService(ContextImpl unused) { 217 synchronized (StaticServiceFetcher.this) { 218 Object service = mCachedInstance; 219 if (service != null) { 220 return service; 221 } 222 return mCachedInstance = createStaticService(); 223 } 224 } 225 226 public abstract Object createStaticService(); 227 } 228 229 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = 230 new HashMap<String, ServiceFetcher>(); 231 232 private static int sNextPerContextServiceCacheIndex = 0; 233 private static void registerService(String serviceName, ServiceFetcher fetcher) { 234 if (!(fetcher instanceof StaticServiceFetcher)) { 235 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++; 236 } 237 SYSTEM_SERVICE_MAP.put(serviceName, fetcher); 238 } 239 240 // This one's defined separately and given a variable name so it 241 // can be re-used by getWallpaperManager(), avoiding a HashMap 242 // lookup. 243 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() { 244 public Object createService(ContextImpl ctx) { 245 return new WallpaperManager(ctx.getOuterContext(), 246 ctx.mMainThread.getHandler()); 247 }}; 248 249 static { 250 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() { 251 public Object getService(ContextImpl ctx) { 252 return AccessibilityManager.getInstance(ctx); 253 }}); 254 255 registerService(ACCOUNT_SERVICE, new ServiceFetcher() { 256 public Object createService(ContextImpl ctx) { 257 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE); 258 IAccountManager service = IAccountManager.Stub.asInterface(b); 259 return new AccountManager(ctx, service); 260 }}); 261 262 registerService(ACTIVITY_SERVICE, new ServiceFetcher() { 263 public Object createService(ContextImpl ctx) { 264 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); 265 }}); 266 267 registerService(ALARM_SERVICE, new StaticServiceFetcher() { 268 public Object createStaticService() { 269 IBinder b = ServiceManager.getService(ALARM_SERVICE); 270 IAlarmManager service = IAlarmManager.Stub.asInterface(b); 271 return new AlarmManager(service); 272 }}); 273 274 registerService(AUDIO_SERVICE, new ServiceFetcher() { 275 public Object createService(ContextImpl ctx) { 276 return new AudioManager(ctx); 277 }}); 278 279 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() { 280 public Object createService(ContextImpl ctx) { 281 return new ClipboardManager(ctx.getOuterContext(), 282 ctx.mMainThread.getHandler()); 283 }}); 284 285 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() { 286 public Object createStaticService() { 287 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE); 288 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b)); 289 }}); 290 291 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() { 292 public Object createStaticService() { 293 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR); 294 return new CountryDetector(ICountryDetector.Stub.asInterface(b)); 295 }}); 296 297 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() { 298 public Object createService(ContextImpl ctx) { 299 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler()); 300 }}); 301 302 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() { 303 public Object createService(ContextImpl ctx) { 304 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName()); 305 }}); 306 307 registerService(NFC_SERVICE, new ServiceFetcher() { 308 public Object createService(ContextImpl ctx) { 309 return new NfcManager(ctx); 310 }}); 311 312 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() { 313 public Object createStaticService() { 314 return createDropBoxManager(); 315 }}); 316 317 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() { 318 public Object createService(ContextImpl ctx) { 319 return InputMethodManager.getInstance(ctx); 320 }}); 321 322 registerService(KEYGUARD_SERVICE, new ServiceFetcher() { 323 public Object getService(ContextImpl ctx) { 324 // TODO: why isn't this caching it? It wasn't 325 // before, so I'm preserving the old behavior and 326 // using getService(), instead of createService() 327 // which would do the caching. 328 return new KeyguardManager(); 329 }}); 330 331 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() { 332 public Object createService(ContextImpl ctx) { 333 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext()); 334 }}); 335 336 registerService(LOCATION_SERVICE, new StaticServiceFetcher() { 337 public Object createStaticService() { 338 IBinder b = ServiceManager.getService(LOCATION_SERVICE); 339 return new LocationManager(ILocationManager.Stub.asInterface(b)); 340 }}); 341 342 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() { 343 public Object createService(ContextImpl ctx) { 344 final Context outerContext = ctx.getOuterContext(); 345 return new NotificationManager( 346 new ContextThemeWrapper(outerContext, 347 Resources.selectSystemTheme(0, 348 outerContext.getApplicationInfo().targetSdkVersion, 349 com.android.internal.R.style.Theme_Dialog, 350 com.android.internal.R.style.Theme_Holo_Dialog)), 351 ctx.mMainThread.getHandler()); 352 }}); 353 354 // Note: this was previously cached in a static variable, but 355 // constructed using mMainThread.getHandler(), so converting 356 // it to be a regular Context-cached service... 357 registerService(POWER_SERVICE, new ServiceFetcher() { 358 public Object createService(ContextImpl ctx) { 359 IBinder b = ServiceManager.getService(POWER_SERVICE); 360 IPowerManager service = IPowerManager.Stub.asInterface(b); 361 return new PowerManager(service, ctx.mMainThread.getHandler()); 362 }}); 363 364 registerService(SEARCH_SERVICE, new ServiceFetcher() { 365 public Object createService(ContextImpl ctx) { 366 return new SearchManager(ctx.getOuterContext(), 367 ctx.mMainThread.getHandler()); 368 }}); 369 370 registerService(SENSOR_SERVICE, new ServiceFetcher() { 371 public Object createService(ContextImpl ctx) { 372 return new SensorManager(ctx.mMainThread.getHandler().getLooper()); 373 }}); 374 375 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() { 376 public Object createService(ContextImpl ctx) { 377 return new StatusBarManager(ctx.getOuterContext()); 378 }}); 379 380 registerService(STORAGE_SERVICE, new ServiceFetcher() { 381 public Object createService(ContextImpl ctx) { 382 try { 383 return new StorageManager(ctx.mMainThread.getHandler().getLooper()); 384 } catch (RemoteException rex) { 385 Log.e(TAG, "Failed to create StorageManager", rex); 386 return null; 387 } 388 }}); 389 390 registerService(TELEPHONY_SERVICE, new ServiceFetcher() { 391 public Object createService(ContextImpl ctx) { 392 return new TelephonyManager(ctx.getOuterContext()); 393 }}); 394 395 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() { 396 public Object createStaticService() { 397 IBinder b = ServiceManager.getService(THROTTLE_SERVICE); 398 return new ThrottleManager(IThrottleManager.Stub.asInterface(b)); 399 }}); 400 401 registerService(UI_MODE_SERVICE, new ServiceFetcher() { 402 public Object createService(ContextImpl ctx) { 403 return new UiModeManager(); 404 }}); 405 406 registerService(USB_SERVICE, new ServiceFetcher() { 407 public Object createService(ContextImpl ctx) { 408 IBinder b = ServiceManager.getService(USB_SERVICE); 409 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b)); 410 }}); 411 412 registerService(VIBRATOR_SERVICE, new ServiceFetcher() { 413 public Object createService(ContextImpl ctx) { 414 return new Vibrator(); 415 }}); 416 417 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER); 418 419 registerService(WIFI_SERVICE, new ServiceFetcher() { 420 public Object createService(ContextImpl ctx) { 421 IBinder b = ServiceManager.getService(WIFI_SERVICE); 422 IWifiManager service = IWifiManager.Stub.asInterface(b); 423 return new WifiManager(service, ctx.mMainThread.getHandler()); 424 }}); 425 426 registerService(WINDOW_SERVICE, new ServiceFetcher() { 427 public Object getService(ContextImpl ctx) { 428 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo); 429 }}); 430 } 431 432 static ContextImpl getImpl(Context context) { 433 Context nextContext; 434 while ((context instanceof ContextWrapper) && 435 (nextContext=((ContextWrapper)context).getBaseContext()) != null) { 436 context = nextContext; 437 } 438 return (ContextImpl)context; 439 } 440 441 // The system service cache for the system services that are 442 // cached per-ContextImpl. Package-scoped to avoid accessor 443 // methods. 444 final ArrayList<Object> mServiceCache = new ArrayList<Object>(); 445 446 @Override 447 public AssetManager getAssets() { 448 return mResources.getAssets(); 449 } 450 451 @Override 452 public Resources getResources() { 453 return mResources; 454 } 455 456 @Override 457 public PackageManager getPackageManager() { 458 if (mPackageManager != null) { 459 return mPackageManager; 460 } 461 462 IPackageManager pm = ActivityThread.getPackageManager(); 463 if (pm != null) { 464 // Doesn't matter if we make more than one instance. 465 return (mPackageManager = new ApplicationPackageManager(this, pm)); 466 } 467 468 return null; 469 } 470 471 @Override 472 public ContentResolver getContentResolver() { 473 return mContentResolver; 474 } 475 476 @Override 477 public Looper getMainLooper() { 478 return mMainThread.getLooper(); 479 } 480 481 @Override 482 public Context getApplicationContext() { 483 return (mPackageInfo != null) ? 484 mPackageInfo.getApplication() : mMainThread.getApplication(); 485 } 486 487 @Override 488 public void setTheme(int resid) { 489 mThemeResource = resid; 490 } 491 492 @Override 493 public int getThemeResId() { 494 return mThemeResource; 495 } 496 497 @Override 498 public Resources.Theme getTheme() { 499 if (mTheme == null) { 500 mThemeResource = Resources.selectDefaultTheme(mThemeResource, 501 getOuterContext().getApplicationInfo().targetSdkVersion); 502 mTheme = mResources.newTheme(); 503 mTheme.applyStyle(mThemeResource, true); 504 } 505 return mTheme; 506 } 507 508 @Override 509 public ClassLoader getClassLoader() { 510 return mPackageInfo != null ? 511 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader(); 512 } 513 514 @Override 515 public String getPackageName() { 516 if (mPackageInfo != null) { 517 return mPackageInfo.getPackageName(); 518 } 519 throw new RuntimeException("Not supported in system context"); 520 } 521 522 @Override 523 public ApplicationInfo getApplicationInfo() { 524 if (mPackageInfo != null) { 525 return mPackageInfo.getApplicationInfo(); 526 } 527 throw new RuntimeException("Not supported in system context"); 528 } 529 530 @Override 531 public String getPackageResourcePath() { 532 if (mPackageInfo != null) { 533 return mPackageInfo.getResDir(); 534 } 535 throw new RuntimeException("Not supported in system context"); 536 } 537 538 @Override 539 public String getPackageCodePath() { 540 if (mPackageInfo != null) { 541 return mPackageInfo.getAppDir(); 542 } 543 throw new RuntimeException("Not supported in system context"); 544 } 545 546 public File getSharedPrefsFile(String name) { 547 return makeFilename(getPreferencesDir(), name + ".xml"); 548 } 549 550 @Override 551 public SharedPreferences getSharedPreferences(String name, int mode) { 552 SharedPreferencesImpl sp; 553 synchronized (sSharedPrefs) { 554 sp = sSharedPrefs.get(name); 555 if (sp == null) { 556 File prefsFile = getSharedPrefsFile(name); 557 sp = new SharedPreferencesImpl(prefsFile, mode); 558 sSharedPrefs.put(name, sp); 559 return sp; 560 } 561 } 562 if ((mode & Context.MODE_MULTI_PROCESS) != 0 || 563 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) { 564 // If somebody else (some other process) changed the prefs 565 // file behind our back, we reload it. This has been the 566 // historical (if undocumented) behavior. 567 sp.startReloadIfChangedUnexpectedly(); 568 } 569 return sp; 570 } 571 572 private File getPreferencesDir() { 573 synchronized (mSync) { 574 if (mPreferencesDir == null) { 575 mPreferencesDir = new File(getDataDirFile(), "shared_prefs"); 576 } 577 return mPreferencesDir; 578 } 579 } 580 581 @Override 582 public FileInputStream openFileInput(String name) 583 throws FileNotFoundException { 584 File f = makeFilename(getFilesDir(), name); 585 return new FileInputStream(f); 586 } 587 588 @Override 589 public FileOutputStream openFileOutput(String name, int mode) 590 throws FileNotFoundException { 591 final boolean append = (mode&MODE_APPEND) != 0; 592 File f = makeFilename(getFilesDir(), name); 593 try { 594 FileOutputStream fos = new FileOutputStream(f, append); 595 setFilePermissionsFromMode(f.getPath(), mode, 0); 596 return fos; 597 } catch (FileNotFoundException e) { 598 } 599 600 File parent = f.getParentFile(); 601 parent.mkdir(); 602 FileUtils.setPermissions( 603 parent.getPath(), 604 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 605 -1, -1); 606 FileOutputStream fos = new FileOutputStream(f, append); 607 setFilePermissionsFromMode(f.getPath(), mode, 0); 608 return fos; 609 } 610 611 @Override 612 public boolean deleteFile(String name) { 613 File f = makeFilename(getFilesDir(), name); 614 return f.delete(); 615 } 616 617 @Override 618 public File getFilesDir() { 619 synchronized (mSync) { 620 if (mFilesDir == null) { 621 mFilesDir = new File(getDataDirFile(), "files"); 622 } 623 if (!mFilesDir.exists()) { 624 if(!mFilesDir.mkdirs()) { 625 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath()); 626 return null; 627 } 628 FileUtils.setPermissions( 629 mFilesDir.getPath(), 630 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 631 -1, -1); 632 } 633 return mFilesDir; 634 } 635 } 636 637 @Override 638 public File getExternalFilesDir(String type) { 639 synchronized (mSync) { 640 if (mExternalFilesDir == null) { 641 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory( 642 getPackageName()); 643 } 644 if (!mExternalFilesDir.exists()) { 645 try { 646 (new File(Environment.getExternalStorageAndroidDataDir(), 647 ".nomedia")).createNewFile(); 648 } catch (IOException e) { 649 } 650 if (!mExternalFilesDir.mkdirs()) { 651 Log.w(TAG, "Unable to create external files directory"); 652 return null; 653 } 654 } 655 if (type == null) { 656 return mExternalFilesDir; 657 } 658 File dir = new File(mExternalFilesDir, type); 659 if (!dir.exists()) { 660 if (!dir.mkdirs()) { 661 Log.w(TAG, "Unable to create external media directory " + dir); 662 return null; 663 } 664 } 665 return dir; 666 } 667 } 668 669 @Override 670 public File getObbDir() { 671 synchronized (mSync) { 672 if (mObbDir == null) { 673 mObbDir = Environment.getExternalStorageAppObbDirectory( 674 getPackageName()); 675 } 676 return mObbDir; 677 } 678 } 679 680 @Override 681 public File getCacheDir() { 682 synchronized (mSync) { 683 if (mCacheDir == null) { 684 mCacheDir = new File(getDataDirFile(), "cache"); 685 } 686 if (!mCacheDir.exists()) { 687 if(!mCacheDir.mkdirs()) { 688 Log.w(TAG, "Unable to create cache directory"); 689 return null; 690 } 691 FileUtils.setPermissions( 692 mCacheDir.getPath(), 693 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 694 -1, -1); 695 } 696 } 697 return mCacheDir; 698 } 699 700 @Override 701 public File getExternalCacheDir() { 702 synchronized (mSync) { 703 if (mExternalCacheDir == null) { 704 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory( 705 getPackageName()); 706 } 707 if (!mExternalCacheDir.exists()) { 708 try { 709 (new File(Environment.getExternalStorageAndroidDataDir(), 710 ".nomedia")).createNewFile(); 711 } catch (IOException e) { 712 } 713 if (!mExternalCacheDir.mkdirs()) { 714 Log.w(TAG, "Unable to create external cache directory"); 715 return null; 716 } 717 } 718 return mExternalCacheDir; 719 } 720 } 721 722 @Override 723 public File getFileStreamPath(String name) { 724 return makeFilename(getFilesDir(), name); 725 } 726 727 @Override 728 public String[] fileList() { 729 final String[] list = getFilesDir().list(); 730 return (list != null) ? list : EMPTY_FILE_LIST; 731 } 732 733 @Override 734 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) { 735 File f = validateFilePath(name, true); 736 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory); 737 setFilePermissionsFromMode(f.getPath(), mode, 0); 738 return db; 739 } 740 741 @Override 742 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, 743 DatabaseErrorHandler errorHandler) { 744 File f = validateFilePath(name, true); 745 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler); 746 setFilePermissionsFromMode(f.getPath(), mode, 0); 747 return db; 748 } 749 750 @Override 751 public boolean deleteDatabase(String name) { 752 try { 753 File f = validateFilePath(name, false); 754 return f.delete(); 755 } catch (Exception e) { 756 } 757 return false; 758 } 759 760 @Override 761 public File getDatabasePath(String name) { 762 return validateFilePath(name, false); 763 } 764 765 @Override 766 public String[] databaseList() { 767 final String[] list = getDatabasesDir().list(); 768 return (list != null) ? list : EMPTY_FILE_LIST; 769 } 770 771 772 private File getDatabasesDir() { 773 synchronized (mSync) { 774 if (mDatabasesDir == null) { 775 mDatabasesDir = new File(getDataDirFile(), "databases"); 776 } 777 if (mDatabasesDir.getPath().equals("databases")) { 778 mDatabasesDir = new File("/data/system"); 779 } 780 return mDatabasesDir; 781 } 782 } 783 784 @Override 785 public Drawable getWallpaper() { 786 return getWallpaperManager().getDrawable(); 787 } 788 789 @Override 790 public Drawable peekWallpaper() { 791 return getWallpaperManager().peekDrawable(); 792 } 793 794 @Override 795 public int getWallpaperDesiredMinimumWidth() { 796 return getWallpaperManager().getDesiredMinimumWidth(); 797 } 798 799 @Override 800 public int getWallpaperDesiredMinimumHeight() { 801 return getWallpaperManager().getDesiredMinimumHeight(); 802 } 803 804 @Override 805 public void setWallpaper(Bitmap bitmap) throws IOException { 806 getWallpaperManager().setBitmap(bitmap); 807 } 808 809 @Override 810 public void setWallpaper(InputStream data) throws IOException { 811 getWallpaperManager().setStream(data); 812 } 813 814 @Override 815 public void clearWallpaper() throws IOException { 816 getWallpaperManager().clear(); 817 } 818 819 @Override 820 public void startActivity(Intent intent) { 821 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 822 throw new AndroidRuntimeException( 823 "Calling startActivity() from outside of an Activity " 824 + " context requires the FLAG_ACTIVITY_NEW_TASK flag." 825 + " Is this really what you want?"); 826 } 827 mMainThread.getInstrumentation().execStartActivity( 828 getOuterContext(), mMainThread.getApplicationThread(), null, 829 (Activity)null, intent, -1); 830 } 831 832 @Override 833 public void startActivities(Intent[] intents) { 834 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 835 throw new AndroidRuntimeException( 836 "Calling startActivities() from outside of an Activity " 837 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent." 838 + " Is this really what you want?"); 839 } 840 mMainThread.getInstrumentation().execStartActivities( 841 getOuterContext(), mMainThread.getApplicationThread(), null, 842 (Activity)null, intents); 843 } 844 845 @Override 846 public void startIntentSender(IntentSender intent, 847 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 848 throws IntentSender.SendIntentException { 849 try { 850 String resolvedType = null; 851 if (fillInIntent != null) { 852 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 853 } 854 int result = ActivityManagerNative.getDefault() 855 .startActivityIntentSender(mMainThread.getApplicationThread(), intent, 856 fillInIntent, resolvedType, null, null, 857 0, flagsMask, flagsValues); 858 if (result == IActivityManager.START_CANCELED) { 859 throw new IntentSender.SendIntentException(); 860 } 861 Instrumentation.checkStartActivityResult(result, null); 862 } catch (RemoteException e) { 863 } 864 } 865 866 @Override 867 public void sendBroadcast(Intent intent) { 868 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 869 try { 870 ActivityManagerNative.getDefault().broadcastIntent( 871 mMainThread.getApplicationThread(), intent, resolvedType, null, 872 Activity.RESULT_OK, null, null, null, false, false); 873 } catch (RemoteException e) { 874 } 875 } 876 877 @Override 878 public void sendBroadcast(Intent intent, String receiverPermission) { 879 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 880 try { 881 ActivityManagerNative.getDefault().broadcastIntent( 882 mMainThread.getApplicationThread(), intent, resolvedType, null, 883 Activity.RESULT_OK, null, null, receiverPermission, false, false); 884 } catch (RemoteException e) { 885 } 886 } 887 888 @Override 889 public void sendOrderedBroadcast(Intent intent, 890 String receiverPermission) { 891 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 892 try { 893 ActivityManagerNative.getDefault().broadcastIntent( 894 mMainThread.getApplicationThread(), intent, resolvedType, null, 895 Activity.RESULT_OK, null, null, receiverPermission, true, false); 896 } catch (RemoteException e) { 897 } 898 } 899 900 @Override 901 public void sendOrderedBroadcast(Intent intent, 902 String receiverPermission, BroadcastReceiver resultReceiver, 903 Handler scheduler, int initialCode, String initialData, 904 Bundle initialExtras) { 905 IIntentReceiver rd = null; 906 if (resultReceiver != null) { 907 if (mPackageInfo != null) { 908 if (scheduler == null) { 909 scheduler = mMainThread.getHandler(); 910 } 911 rd = mPackageInfo.getReceiverDispatcher( 912 resultReceiver, getOuterContext(), scheduler, 913 mMainThread.getInstrumentation(), false); 914 } else { 915 if (scheduler == null) { 916 scheduler = mMainThread.getHandler(); 917 } 918 rd = new LoadedApk.ReceiverDispatcher( 919 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 920 } 921 } 922 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 923 try { 924 ActivityManagerNative.getDefault().broadcastIntent( 925 mMainThread.getApplicationThread(), intent, resolvedType, rd, 926 initialCode, initialData, initialExtras, receiverPermission, 927 true, false); 928 } catch (RemoteException e) { 929 } 930 } 931 932 @Override 933 public void sendStickyBroadcast(Intent intent) { 934 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 935 try { 936 ActivityManagerNative.getDefault().broadcastIntent( 937 mMainThread.getApplicationThread(), intent, resolvedType, null, 938 Activity.RESULT_OK, null, null, null, false, true); 939 } catch (RemoteException e) { 940 } 941 } 942 943 @Override 944 public void sendStickyOrderedBroadcast(Intent intent, 945 BroadcastReceiver resultReceiver, 946 Handler scheduler, int initialCode, String initialData, 947 Bundle initialExtras) { 948 IIntentReceiver rd = null; 949 if (resultReceiver != null) { 950 if (mPackageInfo != null) { 951 if (scheduler == null) { 952 scheduler = mMainThread.getHandler(); 953 } 954 rd = mPackageInfo.getReceiverDispatcher( 955 resultReceiver, getOuterContext(), scheduler, 956 mMainThread.getInstrumentation(), false); 957 } else { 958 if (scheduler == null) { 959 scheduler = mMainThread.getHandler(); 960 } 961 rd = new LoadedApk.ReceiverDispatcher( 962 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 963 } 964 } 965 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 966 try { 967 ActivityManagerNative.getDefault().broadcastIntent( 968 mMainThread.getApplicationThread(), intent, resolvedType, rd, 969 initialCode, initialData, initialExtras, null, 970 true, true); 971 } catch (RemoteException e) { 972 } 973 } 974 975 @Override 976 public void removeStickyBroadcast(Intent intent) { 977 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 978 if (resolvedType != null) { 979 intent = new Intent(intent); 980 intent.setDataAndType(intent.getData(), resolvedType); 981 } 982 try { 983 ActivityManagerNative.getDefault().unbroadcastIntent( 984 mMainThread.getApplicationThread(), intent); 985 } catch (RemoteException e) { 986 } 987 } 988 989 @Override 990 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 991 return registerReceiver(receiver, filter, null, null); 992 } 993 994 @Override 995 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 996 String broadcastPermission, Handler scheduler) { 997 return registerReceiverInternal(receiver, filter, broadcastPermission, 998 scheduler, getOuterContext()); 999 } 1000 1001 private Intent registerReceiverInternal(BroadcastReceiver receiver, 1002 IntentFilter filter, String broadcastPermission, 1003 Handler scheduler, Context context) { 1004 IIntentReceiver rd = null; 1005 if (receiver != null) { 1006 if (mPackageInfo != null && context != null) { 1007 if (scheduler == null) { 1008 scheduler = mMainThread.getHandler(); 1009 } 1010 rd = mPackageInfo.getReceiverDispatcher( 1011 receiver, context, scheduler, 1012 mMainThread.getInstrumentation(), true); 1013 } else { 1014 if (scheduler == null) { 1015 scheduler = mMainThread.getHandler(); 1016 } 1017 rd = new LoadedApk.ReceiverDispatcher( 1018 receiver, context, scheduler, null, true).getIIntentReceiver(); 1019 } 1020 } 1021 try { 1022 return ActivityManagerNative.getDefault().registerReceiver( 1023 mMainThread.getApplicationThread(), 1024 rd, filter, broadcastPermission); 1025 } catch (RemoteException e) { 1026 return null; 1027 } 1028 } 1029 1030 @Override 1031 public void unregisterReceiver(BroadcastReceiver receiver) { 1032 if (mPackageInfo != null) { 1033 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( 1034 getOuterContext(), receiver); 1035 try { 1036 ActivityManagerNative.getDefault().unregisterReceiver(rd); 1037 } catch (RemoteException e) { 1038 } 1039 } else { 1040 throw new RuntimeException("Not supported in system context"); 1041 } 1042 } 1043 1044 @Override 1045 public ComponentName startService(Intent service) { 1046 try { 1047 ComponentName cn = ActivityManagerNative.getDefault().startService( 1048 mMainThread.getApplicationThread(), service, 1049 service.resolveTypeIfNeeded(getContentResolver())); 1050 if (cn != null && cn.getPackageName().equals("!")) { 1051 throw new SecurityException( 1052 "Not allowed to start service " + service 1053 + " without permission " + cn.getClassName()); 1054 } 1055 return cn; 1056 } catch (RemoteException e) { 1057 return null; 1058 } 1059 } 1060 1061 @Override 1062 public boolean stopService(Intent service) { 1063 try { 1064 int res = ActivityManagerNative.getDefault().stopService( 1065 mMainThread.getApplicationThread(), service, 1066 service.resolveTypeIfNeeded(getContentResolver())); 1067 if (res < 0) { 1068 throw new SecurityException( 1069 "Not allowed to stop service " + service); 1070 } 1071 return res != 0; 1072 } catch (RemoteException e) { 1073 return false; 1074 } 1075 } 1076 1077 @Override 1078 public boolean bindService(Intent service, ServiceConnection conn, 1079 int flags) { 1080 IServiceConnection sd; 1081 if (mPackageInfo != null) { 1082 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), 1083 mMainThread.getHandler(), flags); 1084 } else { 1085 throw new RuntimeException("Not supported in system context"); 1086 } 1087 try { 1088 int res = ActivityManagerNative.getDefault().bindService( 1089 mMainThread.getApplicationThread(), getActivityToken(), 1090 service, service.resolveTypeIfNeeded(getContentResolver()), 1091 sd, flags); 1092 if (res < 0) { 1093 throw new SecurityException( 1094 "Not allowed to bind to service " + service); 1095 } 1096 return res != 0; 1097 } catch (RemoteException e) { 1098 return false; 1099 } 1100 } 1101 1102 @Override 1103 public void unbindService(ServiceConnection conn) { 1104 if (mPackageInfo != null) { 1105 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( 1106 getOuterContext(), conn); 1107 try { 1108 ActivityManagerNative.getDefault().unbindService(sd); 1109 } catch (RemoteException e) { 1110 } 1111 } else { 1112 throw new RuntimeException("Not supported in system context"); 1113 } 1114 } 1115 1116 @Override 1117 public boolean startInstrumentation(ComponentName className, 1118 String profileFile, Bundle arguments) { 1119 try { 1120 return ActivityManagerNative.getDefault().startInstrumentation( 1121 className, profileFile, 0, arguments, null); 1122 } catch (RemoteException e) { 1123 // System has crashed, nothing we can do. 1124 } 1125 return false; 1126 } 1127 1128 @Override 1129 public Object getSystemService(String name) { 1130 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); 1131 return fetcher == null ? null : fetcher.getService(this); 1132 } 1133 1134 private WallpaperManager getWallpaperManager() { 1135 return (WallpaperManager) WALLPAPER_FETCHER.getService(this); 1136 } 1137 1138 /* package */ static DropBoxManager createDropBoxManager() { 1139 IBinder b = ServiceManager.getService(DROPBOX_SERVICE); 1140 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b); 1141 if (service == null) { 1142 // Don't return a DropBoxManager that will NPE upon use. 1143 // This also avoids caching a broken DropBoxManager in 1144 // getDropBoxManager during early boot, before the 1145 // DROPBOX_SERVICE is registered. 1146 return null; 1147 } 1148 return new DropBoxManager(service); 1149 } 1150 1151 @Override 1152 public int checkPermission(String permission, int pid, int uid) { 1153 if (permission == null) { 1154 throw new IllegalArgumentException("permission is null"); 1155 } 1156 1157 if (!Process.supportsProcesses()) { 1158 return PackageManager.PERMISSION_GRANTED; 1159 } 1160 try { 1161 return ActivityManagerNative.getDefault().checkPermission( 1162 permission, pid, uid); 1163 } catch (RemoteException e) { 1164 return PackageManager.PERMISSION_DENIED; 1165 } 1166 } 1167 1168 @Override 1169 public int checkCallingPermission(String permission) { 1170 if (permission == null) { 1171 throw new IllegalArgumentException("permission is null"); 1172 } 1173 1174 if (!Process.supportsProcesses()) { 1175 return PackageManager.PERMISSION_GRANTED; 1176 } 1177 int pid = Binder.getCallingPid(); 1178 if (pid != Process.myPid()) { 1179 return checkPermission(permission, pid, 1180 Binder.getCallingUid()); 1181 } 1182 return PackageManager.PERMISSION_DENIED; 1183 } 1184 1185 @Override 1186 public int checkCallingOrSelfPermission(String permission) { 1187 if (permission == null) { 1188 throw new IllegalArgumentException("permission is null"); 1189 } 1190 1191 return checkPermission(permission, Binder.getCallingPid(), 1192 Binder.getCallingUid()); 1193 } 1194 1195 private void enforce( 1196 String permission, int resultOfCheck, 1197 boolean selfToo, int uid, String message) { 1198 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1199 throw new SecurityException( 1200 (message != null ? (message + ": ") : "") + 1201 (selfToo 1202 ? "Neither user " + uid + " nor current process has " 1203 : "User " + uid + " does not have ") + 1204 permission + 1205 "."); 1206 } 1207 } 1208 1209 public void enforcePermission( 1210 String permission, int pid, int uid, String message) { 1211 enforce(permission, 1212 checkPermission(permission, pid, uid), 1213 false, 1214 uid, 1215 message); 1216 } 1217 1218 public void enforceCallingPermission(String permission, String message) { 1219 enforce(permission, 1220 checkCallingPermission(permission), 1221 false, 1222 Binder.getCallingUid(), 1223 message); 1224 } 1225 1226 public void enforceCallingOrSelfPermission( 1227 String permission, String message) { 1228 enforce(permission, 1229 checkCallingOrSelfPermission(permission), 1230 true, 1231 Binder.getCallingUid(), 1232 message); 1233 } 1234 1235 @Override 1236 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) { 1237 try { 1238 ActivityManagerNative.getDefault().grantUriPermission( 1239 mMainThread.getApplicationThread(), toPackage, uri, 1240 modeFlags); 1241 } catch (RemoteException e) { 1242 } 1243 } 1244 1245 @Override 1246 public void revokeUriPermission(Uri uri, int modeFlags) { 1247 try { 1248 ActivityManagerNative.getDefault().revokeUriPermission( 1249 mMainThread.getApplicationThread(), uri, 1250 modeFlags); 1251 } catch (RemoteException e) { 1252 } 1253 } 1254 1255 @Override 1256 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 1257 if (!Process.supportsProcesses()) { 1258 return PackageManager.PERMISSION_GRANTED; 1259 } 1260 try { 1261 return ActivityManagerNative.getDefault().checkUriPermission( 1262 uri, pid, uid, modeFlags); 1263 } catch (RemoteException e) { 1264 return PackageManager.PERMISSION_DENIED; 1265 } 1266 } 1267 1268 @Override 1269 public int checkCallingUriPermission(Uri uri, int modeFlags) { 1270 if (!Process.supportsProcesses()) { 1271 return PackageManager.PERMISSION_GRANTED; 1272 } 1273 int pid = Binder.getCallingPid(); 1274 if (pid != Process.myPid()) { 1275 return checkUriPermission(uri, pid, 1276 Binder.getCallingUid(), modeFlags); 1277 } 1278 return PackageManager.PERMISSION_DENIED; 1279 } 1280 1281 @Override 1282 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) { 1283 return checkUriPermission(uri, Binder.getCallingPid(), 1284 Binder.getCallingUid(), modeFlags); 1285 } 1286 1287 @Override 1288 public int checkUriPermission(Uri uri, String readPermission, 1289 String writePermission, int pid, int uid, int modeFlags) { 1290 if (DEBUG) { 1291 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission=" 1292 + readPermission + " writePermission=" + writePermission 1293 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags); 1294 } 1295 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 1296 if (readPermission == null 1297 || checkPermission(readPermission, pid, uid) 1298 == PackageManager.PERMISSION_GRANTED) { 1299 return PackageManager.PERMISSION_GRANTED; 1300 } 1301 } 1302 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 1303 if (writePermission == null 1304 || checkPermission(writePermission, pid, uid) 1305 == PackageManager.PERMISSION_GRANTED) { 1306 return PackageManager.PERMISSION_GRANTED; 1307 } 1308 } 1309 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags) 1310 : PackageManager.PERMISSION_DENIED; 1311 } 1312 1313 private String uriModeFlagToString(int uriModeFlags) { 1314 switch (uriModeFlags) { 1315 case Intent.FLAG_GRANT_READ_URI_PERMISSION | 1316 Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1317 return "read and write"; 1318 case Intent.FLAG_GRANT_READ_URI_PERMISSION: 1319 return "read"; 1320 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1321 return "write"; 1322 } 1323 throw new IllegalArgumentException( 1324 "Unknown permission mode flags: " + uriModeFlags); 1325 } 1326 1327 private void enforceForUri( 1328 int modeFlags, int resultOfCheck, boolean selfToo, 1329 int uid, Uri uri, String message) { 1330 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1331 throw new SecurityException( 1332 (message != null ? (message + ": ") : "") + 1333 (selfToo 1334 ? "Neither user " + uid + " nor current process has " 1335 : "User " + uid + " does not have ") + 1336 uriModeFlagToString(modeFlags) + 1337 " permission on " + 1338 uri + 1339 "."); 1340 } 1341 } 1342 1343 public void enforceUriPermission( 1344 Uri uri, int pid, int uid, int modeFlags, String message) { 1345 enforceForUri( 1346 modeFlags, checkUriPermission(uri, pid, uid, modeFlags), 1347 false, uid, uri, message); 1348 } 1349 1350 public void enforceCallingUriPermission( 1351 Uri uri, int modeFlags, String message) { 1352 enforceForUri( 1353 modeFlags, checkCallingUriPermission(uri, modeFlags), 1354 false, Binder.getCallingUid(), uri, message); 1355 } 1356 1357 public void enforceCallingOrSelfUriPermission( 1358 Uri uri, int modeFlags, String message) { 1359 enforceForUri( 1360 modeFlags, 1361 checkCallingOrSelfUriPermission(uri, modeFlags), true, 1362 Binder.getCallingUid(), uri, message); 1363 } 1364 1365 public void enforceUriPermission( 1366 Uri uri, String readPermission, String writePermission, 1367 int pid, int uid, int modeFlags, String message) { 1368 enforceForUri(modeFlags, 1369 checkUriPermission( 1370 uri, readPermission, writePermission, pid, uid, 1371 modeFlags), 1372 false, 1373 uid, 1374 uri, 1375 message); 1376 } 1377 1378 @Override 1379 public Context createPackageContext(String packageName, int flags) 1380 throws PackageManager.NameNotFoundException { 1381 if (packageName.equals("system") || packageName.equals("android")) { 1382 return new ContextImpl(mMainThread.getSystemContext()); 1383 } 1384 1385 LoadedApk pi = 1386 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags); 1387 if (pi != null) { 1388 ContextImpl c = new ContextImpl(); 1389 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; 1390 c.init(pi, null, mMainThread, mResources); 1391 if (c.mResources != null) { 1392 return c; 1393 } 1394 } 1395 1396 // Should be a better exception. 1397 throw new PackageManager.NameNotFoundException( 1398 "Application package " + packageName + " not found"); 1399 } 1400 1401 @Override 1402 public boolean isRestricted() { 1403 return mRestricted; 1404 } 1405 1406 private File getDataDirFile() { 1407 if (mPackageInfo != null) { 1408 return mPackageInfo.getDataDirFile(); 1409 } 1410 throw new RuntimeException("Not supported in system context"); 1411 } 1412 1413 @Override 1414 public File getDir(String name, int mode) { 1415 name = "app_" + name; 1416 File file = makeFilename(getDataDirFile(), name); 1417 if (!file.exists()) { 1418 file.mkdir(); 1419 setFilePermissionsFromMode(file.getPath(), mode, 1420 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH); 1421 } 1422 return file; 1423 } 1424 1425 static ContextImpl createSystemContext(ActivityThread mainThread) { 1426 ContextImpl context = new ContextImpl(); 1427 context.init(Resources.getSystem(), mainThread); 1428 return context; 1429 } 1430 1431 ContextImpl() { 1432 mOuterContext = this; 1433 } 1434 1435 /** 1436 * Create a new ApplicationContext from an existing one. The new one 1437 * works and operates the same as the one it is copying. 1438 * 1439 * @param context Existing application context. 1440 */ 1441 public ContextImpl(ContextImpl context) { 1442 mPackageInfo = context.mPackageInfo; 1443 mResources = context.mResources; 1444 mMainThread = context.mMainThread; 1445 mContentResolver = context.mContentResolver; 1446 mOuterContext = this; 1447 } 1448 1449 final void init(LoadedApk packageInfo, 1450 IBinder activityToken, ActivityThread mainThread) { 1451 init(packageInfo, activityToken, mainThread, null); 1452 } 1453 1454 final void init(LoadedApk packageInfo, 1455 IBinder activityToken, ActivityThread mainThread, 1456 Resources container) { 1457 mPackageInfo = packageInfo; 1458 mResources = mPackageInfo.getResources(mainThread); 1459 1460 if (mResources != null && container != null 1461 && container.getCompatibilityInfo().applicationScale != 1462 mResources.getCompatibilityInfo().applicationScale) { 1463 if (DEBUG) { 1464 Log.d(TAG, "loaded context has different scaling. Using container's" + 1465 " compatiblity info:" + container.getDisplayMetrics()); 1466 } 1467 mResources = mainThread.getTopLevelResources( 1468 mPackageInfo.getResDir(), container.getCompatibilityInfo()); 1469 } 1470 mMainThread = mainThread; 1471 mContentResolver = new ApplicationContentResolver(this, mainThread); 1472 1473 setActivityToken(activityToken); 1474 } 1475 1476 final void init(Resources resources, ActivityThread mainThread) { 1477 mPackageInfo = null; 1478 mResources = resources; 1479 mMainThread = mainThread; 1480 mContentResolver = new ApplicationContentResolver(this, mainThread); 1481 } 1482 1483 final void scheduleFinalCleanup(String who, String what) { 1484 mMainThread.scheduleContextCleanup(this, who, what); 1485 } 1486 1487 final void performFinalCleanup(String who, String what) { 1488 //Log.i(TAG, "Cleanup up context: " + this); 1489 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); 1490 } 1491 1492 final Context getReceiverRestrictedContext() { 1493 if (mReceiverRestrictedContext != null) { 1494 return mReceiverRestrictedContext; 1495 } 1496 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext()); 1497 } 1498 1499 final void setActivityToken(IBinder token) { 1500 mActivityToken = token; 1501 } 1502 1503 final void setOuterContext(Context context) { 1504 mOuterContext = context; 1505 } 1506 1507 final Context getOuterContext() { 1508 return mOuterContext; 1509 } 1510 1511 final IBinder getActivityToken() { 1512 return mActivityToken; 1513 } 1514 1515 static void setFilePermissionsFromMode(String name, int mode, 1516 int extraPermissions) { 1517 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR 1518 |FileUtils.S_IRGRP|FileUtils.S_IWGRP 1519 |extraPermissions; 1520 if ((mode&MODE_WORLD_READABLE) != 0) { 1521 perms |= FileUtils.S_IROTH; 1522 } 1523 if ((mode&MODE_WORLD_WRITEABLE) != 0) { 1524 perms |= FileUtils.S_IWOTH; 1525 } 1526 if (DEBUG) { 1527 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode) 1528 + ", perms=0x" + Integer.toHexString(perms)); 1529 } 1530 FileUtils.setPermissions(name, perms, -1, -1); 1531 } 1532 1533 private File validateFilePath(String name, boolean createDirectory) { 1534 File dir; 1535 File f; 1536 1537 if (name.charAt(0) == File.separatorChar) { 1538 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar)); 1539 dir = new File(dirPath); 1540 name = name.substring(name.lastIndexOf(File.separatorChar)); 1541 f = new File(dir, name); 1542 } else { 1543 dir = getDatabasesDir(); 1544 f = makeFilename(dir, name); 1545 } 1546 1547 if (createDirectory && !dir.isDirectory() && dir.mkdir()) { 1548 FileUtils.setPermissions(dir.getPath(), 1549 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 1550 -1, -1); 1551 } 1552 1553 return f; 1554 } 1555 1556 private File makeFilename(File base, String name) { 1557 if (name.indexOf(File.separatorChar) < 0) { 1558 return new File(base, name); 1559 } 1560 throw new IllegalArgumentException( 1561 "File " + name + " contains a path separator"); 1562 } 1563 1564 // ---------------------------------------------------------------------- 1565 // ---------------------------------------------------------------------- 1566 // ---------------------------------------------------------------------- 1567 1568 private static final class ApplicationContentResolver extends ContentResolver { 1569 public ApplicationContentResolver(Context context, ActivityThread mainThread) { 1570 super(context); 1571 mMainThread = mainThread; 1572 } 1573 1574 @Override 1575 protected IContentProvider acquireProvider(Context context, String name) { 1576 return mMainThread.acquireProvider(context, name); 1577 } 1578 1579 @Override 1580 protected IContentProvider acquireExistingProvider(Context context, String name) { 1581 return mMainThread.acquireExistingProvider(context, name); 1582 } 1583 1584 @Override 1585 public boolean releaseProvider(IContentProvider provider) { 1586 return mMainThread.releaseProvider(provider); 1587 } 1588 1589 private final ActivityThread mMainThread; 1590 } 1591} 1592