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