ContextImpl.java revision 5be8de3420ba4c9d816b98e29bdec11715f6b626
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 RuntimeException e = new RuntimeException("foo"); 429 e.fillInStackTrace(); 430 Log.i(TAG, "Getting window manager", e); 431 CompatibilityInfo ci = ctx.mResources.getCompatibilityInfo(); 432 return WindowManagerImpl.getDefault(ci); 433 }}); 434 } 435 436 // The system service cache for the system services that are 437 // cached per-ContextImpl. Package-scoped to avoid accessor 438 // methods. 439 final ArrayList<Object> mServiceCache = new ArrayList<Object>(); 440 441 @Override 442 public AssetManager getAssets() { 443 return mResources.getAssets(); 444 } 445 446 @Override 447 public Resources getResources() { 448 return mResources; 449 } 450 451 @Override 452 public PackageManager getPackageManager() { 453 if (mPackageManager != null) { 454 return mPackageManager; 455 } 456 457 IPackageManager pm = ActivityThread.getPackageManager(); 458 if (pm != null) { 459 // Doesn't matter if we make more than one instance. 460 return (mPackageManager = new ApplicationPackageManager(this, pm)); 461 } 462 463 return null; 464 } 465 466 @Override 467 public ContentResolver getContentResolver() { 468 return mContentResolver; 469 } 470 471 @Override 472 public Looper getMainLooper() { 473 return mMainThread.getLooper(); 474 } 475 476 @Override 477 public Context getApplicationContext() { 478 return (mPackageInfo != null) ? 479 mPackageInfo.getApplication() : mMainThread.getApplication(); 480 } 481 482 @Override 483 public void setTheme(int resid) { 484 mThemeResource = resid; 485 } 486 487 @Override 488 public int getThemeResId() { 489 return mThemeResource; 490 } 491 492 @Override 493 public Resources.Theme getTheme() { 494 if (mTheme == null) { 495 mThemeResource = Resources.selectDefaultTheme(mThemeResource, 496 getOuterContext().getApplicationInfo().targetSdkVersion); 497 mTheme = mResources.newTheme(); 498 mTheme.applyStyle(mThemeResource, true); 499 } 500 return mTheme; 501 } 502 503 @Override 504 public ClassLoader getClassLoader() { 505 return mPackageInfo != null ? 506 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader(); 507 } 508 509 @Override 510 public String getPackageName() { 511 if (mPackageInfo != null) { 512 return mPackageInfo.getPackageName(); 513 } 514 throw new RuntimeException("Not supported in system context"); 515 } 516 517 @Override 518 public ApplicationInfo getApplicationInfo() { 519 if (mPackageInfo != null) { 520 return mPackageInfo.getApplicationInfo(); 521 } 522 throw new RuntimeException("Not supported in system context"); 523 } 524 525 @Override 526 public String getPackageResourcePath() { 527 if (mPackageInfo != null) { 528 return mPackageInfo.getResDir(); 529 } 530 throw new RuntimeException("Not supported in system context"); 531 } 532 533 @Override 534 public String getPackageCodePath() { 535 if (mPackageInfo != null) { 536 return mPackageInfo.getAppDir(); 537 } 538 throw new RuntimeException("Not supported in system context"); 539 } 540 541 public File getSharedPrefsFile(String name) { 542 return makeFilename(getPreferencesDir(), name + ".xml"); 543 } 544 545 @Override 546 public SharedPreferences getSharedPreferences(String name, int mode) { 547 SharedPreferencesImpl sp; 548 synchronized (sSharedPrefs) { 549 sp = sSharedPrefs.get(name); 550 if (sp == null) { 551 File prefsFile = getSharedPrefsFile(name); 552 sp = new SharedPreferencesImpl(prefsFile, mode); 553 sSharedPrefs.put(name, sp); 554 return sp; 555 } 556 } 557 if ((mode & Context.MODE_MULTI_PROCESS) != 0 || 558 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) { 559 // If somebody else (some other process) changed the prefs 560 // file behind our back, we reload it. This has been the 561 // historical (if undocumented) behavior. 562 sp.startReloadIfChangedUnexpectedly(); 563 } 564 return sp; 565 } 566 567 private File getPreferencesDir() { 568 synchronized (mSync) { 569 if (mPreferencesDir == null) { 570 mPreferencesDir = new File(getDataDirFile(), "shared_prefs"); 571 } 572 return mPreferencesDir; 573 } 574 } 575 576 @Override 577 public FileInputStream openFileInput(String name) 578 throws FileNotFoundException { 579 File f = makeFilename(getFilesDir(), name); 580 return new FileInputStream(f); 581 } 582 583 @Override 584 public FileOutputStream openFileOutput(String name, int mode) 585 throws FileNotFoundException { 586 final boolean append = (mode&MODE_APPEND) != 0; 587 File f = makeFilename(getFilesDir(), name); 588 try { 589 FileOutputStream fos = new FileOutputStream(f, append); 590 setFilePermissionsFromMode(f.getPath(), mode, 0); 591 return fos; 592 } catch (FileNotFoundException e) { 593 } 594 595 File parent = f.getParentFile(); 596 parent.mkdir(); 597 FileUtils.setPermissions( 598 parent.getPath(), 599 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 600 -1, -1); 601 FileOutputStream fos = new FileOutputStream(f, append); 602 setFilePermissionsFromMode(f.getPath(), mode, 0); 603 return fos; 604 } 605 606 @Override 607 public boolean deleteFile(String name) { 608 File f = makeFilename(getFilesDir(), name); 609 return f.delete(); 610 } 611 612 @Override 613 public File getFilesDir() { 614 synchronized (mSync) { 615 if (mFilesDir == null) { 616 mFilesDir = new File(getDataDirFile(), "files"); 617 } 618 if (!mFilesDir.exists()) { 619 if(!mFilesDir.mkdirs()) { 620 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath()); 621 return null; 622 } 623 FileUtils.setPermissions( 624 mFilesDir.getPath(), 625 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 626 -1, -1); 627 } 628 return mFilesDir; 629 } 630 } 631 632 @Override 633 public File getExternalFilesDir(String type) { 634 synchronized (mSync) { 635 if (mExternalFilesDir == null) { 636 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory( 637 getPackageName()); 638 } 639 if (!mExternalFilesDir.exists()) { 640 try { 641 (new File(Environment.getExternalStorageAndroidDataDir(), 642 ".nomedia")).createNewFile(); 643 } catch (IOException e) { 644 } 645 if (!mExternalFilesDir.mkdirs()) { 646 Log.w(TAG, "Unable to create external files directory"); 647 return null; 648 } 649 } 650 if (type == null) { 651 return mExternalFilesDir; 652 } 653 File dir = new File(mExternalFilesDir, type); 654 if (!dir.exists()) { 655 if (!dir.mkdirs()) { 656 Log.w(TAG, "Unable to create external media directory " + dir); 657 return null; 658 } 659 } 660 return dir; 661 } 662 } 663 664 @Override 665 public File getObbDir() { 666 synchronized (mSync) { 667 if (mObbDir == null) { 668 mObbDir = Environment.getExternalStorageAppObbDirectory( 669 getPackageName()); 670 } 671 return mObbDir; 672 } 673 } 674 675 @Override 676 public File getCacheDir() { 677 synchronized (mSync) { 678 if (mCacheDir == null) { 679 mCacheDir = new File(getDataDirFile(), "cache"); 680 } 681 if (!mCacheDir.exists()) { 682 if(!mCacheDir.mkdirs()) { 683 Log.w(TAG, "Unable to create cache directory"); 684 return null; 685 } 686 FileUtils.setPermissions( 687 mCacheDir.getPath(), 688 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 689 -1, -1); 690 } 691 } 692 return mCacheDir; 693 } 694 695 @Override 696 public File getExternalCacheDir() { 697 synchronized (mSync) { 698 if (mExternalCacheDir == null) { 699 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory( 700 getPackageName()); 701 } 702 if (!mExternalCacheDir.exists()) { 703 try { 704 (new File(Environment.getExternalStorageAndroidDataDir(), 705 ".nomedia")).createNewFile(); 706 } catch (IOException e) { 707 } 708 if (!mExternalCacheDir.mkdirs()) { 709 Log.w(TAG, "Unable to create external cache directory"); 710 return null; 711 } 712 } 713 return mExternalCacheDir; 714 } 715 } 716 717 @Override 718 public File getFileStreamPath(String name) { 719 return makeFilename(getFilesDir(), name); 720 } 721 722 @Override 723 public String[] fileList() { 724 final String[] list = getFilesDir().list(); 725 return (list != null) ? list : EMPTY_FILE_LIST; 726 } 727 728 @Override 729 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) { 730 File f = validateFilePath(name, true); 731 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory); 732 setFilePermissionsFromMode(f.getPath(), mode, 0); 733 return db; 734 } 735 736 @Override 737 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, 738 DatabaseErrorHandler errorHandler) { 739 File f = validateFilePath(name, true); 740 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler); 741 setFilePermissionsFromMode(f.getPath(), mode, 0); 742 return db; 743 } 744 745 @Override 746 public boolean deleteDatabase(String name) { 747 try { 748 File f = validateFilePath(name, false); 749 return f.delete(); 750 } catch (Exception e) { 751 } 752 return false; 753 } 754 755 @Override 756 public File getDatabasePath(String name) { 757 return validateFilePath(name, false); 758 } 759 760 @Override 761 public String[] databaseList() { 762 final String[] list = getDatabasesDir().list(); 763 return (list != null) ? list : EMPTY_FILE_LIST; 764 } 765 766 767 private File getDatabasesDir() { 768 synchronized (mSync) { 769 if (mDatabasesDir == null) { 770 mDatabasesDir = new File(getDataDirFile(), "databases"); 771 } 772 if (mDatabasesDir.getPath().equals("databases")) { 773 mDatabasesDir = new File("/data/system"); 774 } 775 return mDatabasesDir; 776 } 777 } 778 779 @Override 780 public Drawable getWallpaper() { 781 return getWallpaperManager().getDrawable(); 782 } 783 784 @Override 785 public Drawable peekWallpaper() { 786 return getWallpaperManager().peekDrawable(); 787 } 788 789 @Override 790 public int getWallpaperDesiredMinimumWidth() { 791 return getWallpaperManager().getDesiredMinimumWidth(); 792 } 793 794 @Override 795 public int getWallpaperDesiredMinimumHeight() { 796 return getWallpaperManager().getDesiredMinimumHeight(); 797 } 798 799 @Override 800 public void setWallpaper(Bitmap bitmap) throws IOException { 801 getWallpaperManager().setBitmap(bitmap); 802 } 803 804 @Override 805 public void setWallpaper(InputStream data) throws IOException { 806 getWallpaperManager().setStream(data); 807 } 808 809 @Override 810 public void clearWallpaper() throws IOException { 811 getWallpaperManager().clear(); 812 } 813 814 @Override 815 public void startActivity(Intent intent) { 816 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 817 throw new AndroidRuntimeException( 818 "Calling startActivity() from outside of an Activity " 819 + " context requires the FLAG_ACTIVITY_NEW_TASK flag." 820 + " Is this really what you want?"); 821 } 822 mMainThread.getInstrumentation().execStartActivity( 823 getOuterContext(), mMainThread.getApplicationThread(), null, 824 (Activity)null, intent, -1); 825 } 826 827 @Override 828 public void startActivities(Intent[] intents) { 829 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 830 throw new AndroidRuntimeException( 831 "Calling startActivities() from outside of an Activity " 832 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent." 833 + " Is this really what you want?"); 834 } 835 mMainThread.getInstrumentation().execStartActivities( 836 getOuterContext(), mMainThread.getApplicationThread(), null, 837 (Activity)null, intents); 838 } 839 840 @Override 841 public void startIntentSender(IntentSender intent, 842 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 843 throws IntentSender.SendIntentException { 844 try { 845 String resolvedType = null; 846 if (fillInIntent != null) { 847 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 848 } 849 int result = ActivityManagerNative.getDefault() 850 .startActivityIntentSender(mMainThread.getApplicationThread(), intent, 851 fillInIntent, resolvedType, null, null, 852 0, flagsMask, flagsValues); 853 if (result == IActivityManager.START_CANCELED) { 854 throw new IntentSender.SendIntentException(); 855 } 856 Instrumentation.checkStartActivityResult(result, null); 857 } catch (RemoteException e) { 858 } 859 } 860 861 @Override 862 public void sendBroadcast(Intent intent) { 863 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 864 try { 865 ActivityManagerNative.getDefault().broadcastIntent( 866 mMainThread.getApplicationThread(), intent, resolvedType, null, 867 Activity.RESULT_OK, null, null, null, false, false); 868 } catch (RemoteException e) { 869 } 870 } 871 872 @Override 873 public void sendBroadcast(Intent intent, String receiverPermission) { 874 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 875 try { 876 ActivityManagerNative.getDefault().broadcastIntent( 877 mMainThread.getApplicationThread(), intent, resolvedType, null, 878 Activity.RESULT_OK, null, null, receiverPermission, false, false); 879 } catch (RemoteException e) { 880 } 881 } 882 883 @Override 884 public void sendOrderedBroadcast(Intent intent, 885 String receiverPermission) { 886 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 887 try { 888 ActivityManagerNative.getDefault().broadcastIntent( 889 mMainThread.getApplicationThread(), intent, resolvedType, null, 890 Activity.RESULT_OK, null, null, receiverPermission, true, false); 891 } catch (RemoteException e) { 892 } 893 } 894 895 @Override 896 public void sendOrderedBroadcast(Intent intent, 897 String receiverPermission, BroadcastReceiver resultReceiver, 898 Handler scheduler, int initialCode, String initialData, 899 Bundle initialExtras) { 900 IIntentReceiver rd = null; 901 if (resultReceiver != null) { 902 if (mPackageInfo != null) { 903 if (scheduler == null) { 904 scheduler = mMainThread.getHandler(); 905 } 906 rd = mPackageInfo.getReceiverDispatcher( 907 resultReceiver, getOuterContext(), scheduler, 908 mMainThread.getInstrumentation(), false); 909 } else { 910 if (scheduler == null) { 911 scheduler = mMainThread.getHandler(); 912 } 913 rd = new LoadedApk.ReceiverDispatcher( 914 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 915 } 916 } 917 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 918 try { 919 ActivityManagerNative.getDefault().broadcastIntent( 920 mMainThread.getApplicationThread(), intent, resolvedType, rd, 921 initialCode, initialData, initialExtras, receiverPermission, 922 true, false); 923 } catch (RemoteException e) { 924 } 925 } 926 927 @Override 928 public void sendStickyBroadcast(Intent intent) { 929 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 930 try { 931 ActivityManagerNative.getDefault().broadcastIntent( 932 mMainThread.getApplicationThread(), intent, resolvedType, null, 933 Activity.RESULT_OK, null, null, null, false, true); 934 } catch (RemoteException e) { 935 } 936 } 937 938 @Override 939 public void sendStickyOrderedBroadcast(Intent intent, 940 BroadcastReceiver resultReceiver, 941 Handler scheduler, int initialCode, String initialData, 942 Bundle initialExtras) { 943 IIntentReceiver rd = null; 944 if (resultReceiver != null) { 945 if (mPackageInfo != null) { 946 if (scheduler == null) { 947 scheduler = mMainThread.getHandler(); 948 } 949 rd = mPackageInfo.getReceiverDispatcher( 950 resultReceiver, getOuterContext(), scheduler, 951 mMainThread.getInstrumentation(), false); 952 } else { 953 if (scheduler == null) { 954 scheduler = mMainThread.getHandler(); 955 } 956 rd = new LoadedApk.ReceiverDispatcher( 957 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 958 } 959 } 960 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 961 try { 962 ActivityManagerNative.getDefault().broadcastIntent( 963 mMainThread.getApplicationThread(), intent, resolvedType, rd, 964 initialCode, initialData, initialExtras, null, 965 true, true); 966 } catch (RemoteException e) { 967 } 968 } 969 970 @Override 971 public void removeStickyBroadcast(Intent intent) { 972 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 973 if (resolvedType != null) { 974 intent = new Intent(intent); 975 intent.setDataAndType(intent.getData(), resolvedType); 976 } 977 try { 978 ActivityManagerNative.getDefault().unbroadcastIntent( 979 mMainThread.getApplicationThread(), intent); 980 } catch (RemoteException e) { 981 } 982 } 983 984 @Override 985 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 986 return registerReceiver(receiver, filter, null, null); 987 } 988 989 @Override 990 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 991 String broadcastPermission, Handler scheduler) { 992 return registerReceiverInternal(receiver, filter, broadcastPermission, 993 scheduler, getOuterContext()); 994 } 995 996 private Intent registerReceiverInternal(BroadcastReceiver receiver, 997 IntentFilter filter, String broadcastPermission, 998 Handler scheduler, Context context) { 999 IIntentReceiver rd = null; 1000 if (receiver != null) { 1001 if (mPackageInfo != null && context != null) { 1002 if (scheduler == null) { 1003 scheduler = mMainThread.getHandler(); 1004 } 1005 rd = mPackageInfo.getReceiverDispatcher( 1006 receiver, context, scheduler, 1007 mMainThread.getInstrumentation(), true); 1008 } else { 1009 if (scheduler == null) { 1010 scheduler = mMainThread.getHandler(); 1011 } 1012 rd = new LoadedApk.ReceiverDispatcher( 1013 receiver, context, scheduler, null, true).getIIntentReceiver(); 1014 } 1015 } 1016 try { 1017 return ActivityManagerNative.getDefault().registerReceiver( 1018 mMainThread.getApplicationThread(), 1019 rd, filter, broadcastPermission); 1020 } catch (RemoteException e) { 1021 return null; 1022 } 1023 } 1024 1025 @Override 1026 public void unregisterReceiver(BroadcastReceiver receiver) { 1027 if (mPackageInfo != null) { 1028 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( 1029 getOuterContext(), receiver); 1030 try { 1031 ActivityManagerNative.getDefault().unregisterReceiver(rd); 1032 } catch (RemoteException e) { 1033 } 1034 } else { 1035 throw new RuntimeException("Not supported in system context"); 1036 } 1037 } 1038 1039 @Override 1040 public ComponentName startService(Intent service) { 1041 try { 1042 ComponentName cn = ActivityManagerNative.getDefault().startService( 1043 mMainThread.getApplicationThread(), service, 1044 service.resolveTypeIfNeeded(getContentResolver())); 1045 if (cn != null && cn.getPackageName().equals("!")) { 1046 throw new SecurityException( 1047 "Not allowed to start service " + service 1048 + " without permission " + cn.getClassName()); 1049 } 1050 return cn; 1051 } catch (RemoteException e) { 1052 return null; 1053 } 1054 } 1055 1056 @Override 1057 public boolean stopService(Intent service) { 1058 try { 1059 int res = ActivityManagerNative.getDefault().stopService( 1060 mMainThread.getApplicationThread(), service, 1061 service.resolveTypeIfNeeded(getContentResolver())); 1062 if (res < 0) { 1063 throw new SecurityException( 1064 "Not allowed to stop service " + service); 1065 } 1066 return res != 0; 1067 } catch (RemoteException e) { 1068 return false; 1069 } 1070 } 1071 1072 @Override 1073 public boolean bindService(Intent service, ServiceConnection conn, 1074 int flags) { 1075 IServiceConnection sd; 1076 if (mPackageInfo != null) { 1077 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), 1078 mMainThread.getHandler(), flags); 1079 } else { 1080 throw new RuntimeException("Not supported in system context"); 1081 } 1082 try { 1083 int res = ActivityManagerNative.getDefault().bindService( 1084 mMainThread.getApplicationThread(), getActivityToken(), 1085 service, service.resolveTypeIfNeeded(getContentResolver()), 1086 sd, flags); 1087 if (res < 0) { 1088 throw new SecurityException( 1089 "Not allowed to bind to service " + service); 1090 } 1091 return res != 0; 1092 } catch (RemoteException e) { 1093 return false; 1094 } 1095 } 1096 1097 @Override 1098 public void unbindService(ServiceConnection conn) { 1099 if (mPackageInfo != null) { 1100 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( 1101 getOuterContext(), conn); 1102 try { 1103 ActivityManagerNative.getDefault().unbindService(sd); 1104 } catch (RemoteException e) { 1105 } 1106 } else { 1107 throw new RuntimeException("Not supported in system context"); 1108 } 1109 } 1110 1111 @Override 1112 public boolean startInstrumentation(ComponentName className, 1113 String profileFile, Bundle arguments) { 1114 try { 1115 return ActivityManagerNative.getDefault().startInstrumentation( 1116 className, profileFile, 0, arguments, null); 1117 } catch (RemoteException e) { 1118 // System has crashed, nothing we can do. 1119 } 1120 return false; 1121 } 1122 1123 @Override 1124 public Object getSystemService(String name) { 1125 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); 1126 return fetcher == null ? null : fetcher.getService(this); 1127 } 1128 1129 private WallpaperManager getWallpaperManager() { 1130 return (WallpaperManager) WALLPAPER_FETCHER.getService(this); 1131 } 1132 1133 /* package */ static DropBoxManager createDropBoxManager() { 1134 IBinder b = ServiceManager.getService(DROPBOX_SERVICE); 1135 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b); 1136 if (service == null) { 1137 // Don't return a DropBoxManager that will NPE upon use. 1138 // This also avoids caching a broken DropBoxManager in 1139 // getDropBoxManager during early boot, before the 1140 // DROPBOX_SERVICE is registered. 1141 return null; 1142 } 1143 return new DropBoxManager(service); 1144 } 1145 1146 @Override 1147 public int checkPermission(String permission, int pid, int uid) { 1148 if (permission == null) { 1149 throw new IllegalArgumentException("permission is null"); 1150 } 1151 1152 if (!Process.supportsProcesses()) { 1153 return PackageManager.PERMISSION_GRANTED; 1154 } 1155 try { 1156 return ActivityManagerNative.getDefault().checkPermission( 1157 permission, pid, uid); 1158 } catch (RemoteException e) { 1159 return PackageManager.PERMISSION_DENIED; 1160 } 1161 } 1162 1163 @Override 1164 public int checkCallingPermission(String permission) { 1165 if (permission == null) { 1166 throw new IllegalArgumentException("permission is null"); 1167 } 1168 1169 if (!Process.supportsProcesses()) { 1170 return PackageManager.PERMISSION_GRANTED; 1171 } 1172 int pid = Binder.getCallingPid(); 1173 if (pid != Process.myPid()) { 1174 return checkPermission(permission, pid, 1175 Binder.getCallingUid()); 1176 } 1177 return PackageManager.PERMISSION_DENIED; 1178 } 1179 1180 @Override 1181 public int checkCallingOrSelfPermission(String permission) { 1182 if (permission == null) { 1183 throw new IllegalArgumentException("permission is null"); 1184 } 1185 1186 return checkPermission(permission, Binder.getCallingPid(), 1187 Binder.getCallingUid()); 1188 } 1189 1190 private void enforce( 1191 String permission, int resultOfCheck, 1192 boolean selfToo, int uid, String message) { 1193 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1194 throw new SecurityException( 1195 (message != null ? (message + ": ") : "") + 1196 (selfToo 1197 ? "Neither user " + uid + " nor current process has " 1198 : "User " + uid + " does not have ") + 1199 permission + 1200 "."); 1201 } 1202 } 1203 1204 public void enforcePermission( 1205 String permission, int pid, int uid, String message) { 1206 enforce(permission, 1207 checkPermission(permission, pid, uid), 1208 false, 1209 uid, 1210 message); 1211 } 1212 1213 public void enforceCallingPermission(String permission, String message) { 1214 enforce(permission, 1215 checkCallingPermission(permission), 1216 false, 1217 Binder.getCallingUid(), 1218 message); 1219 } 1220 1221 public void enforceCallingOrSelfPermission( 1222 String permission, String message) { 1223 enforce(permission, 1224 checkCallingOrSelfPermission(permission), 1225 true, 1226 Binder.getCallingUid(), 1227 message); 1228 } 1229 1230 @Override 1231 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) { 1232 try { 1233 ActivityManagerNative.getDefault().grantUriPermission( 1234 mMainThread.getApplicationThread(), toPackage, uri, 1235 modeFlags); 1236 } catch (RemoteException e) { 1237 } 1238 } 1239 1240 @Override 1241 public void revokeUriPermission(Uri uri, int modeFlags) { 1242 try { 1243 ActivityManagerNative.getDefault().revokeUriPermission( 1244 mMainThread.getApplicationThread(), uri, 1245 modeFlags); 1246 } catch (RemoteException e) { 1247 } 1248 } 1249 1250 @Override 1251 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 1252 if (!Process.supportsProcesses()) { 1253 return PackageManager.PERMISSION_GRANTED; 1254 } 1255 try { 1256 return ActivityManagerNative.getDefault().checkUriPermission( 1257 uri, pid, uid, modeFlags); 1258 } catch (RemoteException e) { 1259 return PackageManager.PERMISSION_DENIED; 1260 } 1261 } 1262 1263 @Override 1264 public int checkCallingUriPermission(Uri uri, int modeFlags) { 1265 if (!Process.supportsProcesses()) { 1266 return PackageManager.PERMISSION_GRANTED; 1267 } 1268 int pid = Binder.getCallingPid(); 1269 if (pid != Process.myPid()) { 1270 return checkUriPermission(uri, pid, 1271 Binder.getCallingUid(), modeFlags); 1272 } 1273 return PackageManager.PERMISSION_DENIED; 1274 } 1275 1276 @Override 1277 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) { 1278 return checkUriPermission(uri, Binder.getCallingPid(), 1279 Binder.getCallingUid(), modeFlags); 1280 } 1281 1282 @Override 1283 public int checkUriPermission(Uri uri, String readPermission, 1284 String writePermission, int pid, int uid, int modeFlags) { 1285 if (DEBUG) { 1286 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission=" 1287 + readPermission + " writePermission=" + writePermission 1288 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags); 1289 } 1290 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 1291 if (readPermission == null 1292 || checkPermission(readPermission, pid, uid) 1293 == PackageManager.PERMISSION_GRANTED) { 1294 return PackageManager.PERMISSION_GRANTED; 1295 } 1296 } 1297 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 1298 if (writePermission == null 1299 || checkPermission(writePermission, pid, uid) 1300 == PackageManager.PERMISSION_GRANTED) { 1301 return PackageManager.PERMISSION_GRANTED; 1302 } 1303 } 1304 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags) 1305 : PackageManager.PERMISSION_DENIED; 1306 } 1307 1308 private String uriModeFlagToString(int uriModeFlags) { 1309 switch (uriModeFlags) { 1310 case Intent.FLAG_GRANT_READ_URI_PERMISSION | 1311 Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1312 return "read and write"; 1313 case Intent.FLAG_GRANT_READ_URI_PERMISSION: 1314 return "read"; 1315 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1316 return "write"; 1317 } 1318 throw new IllegalArgumentException( 1319 "Unknown permission mode flags: " + uriModeFlags); 1320 } 1321 1322 private void enforceForUri( 1323 int modeFlags, int resultOfCheck, boolean selfToo, 1324 int uid, Uri uri, String message) { 1325 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1326 throw new SecurityException( 1327 (message != null ? (message + ": ") : "") + 1328 (selfToo 1329 ? "Neither user " + uid + " nor current process has " 1330 : "User " + uid + " does not have ") + 1331 uriModeFlagToString(modeFlags) + 1332 " permission on " + 1333 uri + 1334 "."); 1335 } 1336 } 1337 1338 public void enforceUriPermission( 1339 Uri uri, int pid, int uid, int modeFlags, String message) { 1340 enforceForUri( 1341 modeFlags, checkUriPermission(uri, pid, uid, modeFlags), 1342 false, uid, uri, message); 1343 } 1344 1345 public void enforceCallingUriPermission( 1346 Uri uri, int modeFlags, String message) { 1347 enforceForUri( 1348 modeFlags, checkCallingUriPermission(uri, modeFlags), 1349 false, Binder.getCallingUid(), uri, message); 1350 } 1351 1352 public void enforceCallingOrSelfUriPermission( 1353 Uri uri, int modeFlags, String message) { 1354 enforceForUri( 1355 modeFlags, 1356 checkCallingOrSelfUriPermission(uri, modeFlags), true, 1357 Binder.getCallingUid(), uri, message); 1358 } 1359 1360 public void enforceUriPermission( 1361 Uri uri, String readPermission, String writePermission, 1362 int pid, int uid, int modeFlags, String message) { 1363 enforceForUri(modeFlags, 1364 checkUriPermission( 1365 uri, readPermission, writePermission, pid, uid, 1366 modeFlags), 1367 false, 1368 uid, 1369 uri, 1370 message); 1371 } 1372 1373 @Override 1374 public Context createPackageContext(String packageName, int flags) 1375 throws PackageManager.NameNotFoundException { 1376 if (packageName.equals("system") || packageName.equals("android")) { 1377 return new ContextImpl(mMainThread.getSystemContext()); 1378 } 1379 1380 LoadedApk pi = 1381 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags); 1382 if (pi != null) { 1383 ContextImpl c = new ContextImpl(); 1384 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; 1385 c.init(pi, null, mMainThread, mResources); 1386 if (c.mResources != null) { 1387 return c; 1388 } 1389 } 1390 1391 // Should be a better exception. 1392 throw new PackageManager.NameNotFoundException( 1393 "Application package " + packageName + " not found"); 1394 } 1395 1396 @Override 1397 public boolean isRestricted() { 1398 return mRestricted; 1399 } 1400 1401 private File getDataDirFile() { 1402 if (mPackageInfo != null) { 1403 return mPackageInfo.getDataDirFile(); 1404 } 1405 throw new RuntimeException("Not supported in system context"); 1406 } 1407 1408 @Override 1409 public File getDir(String name, int mode) { 1410 name = "app_" + name; 1411 File file = makeFilename(getDataDirFile(), name); 1412 if (!file.exists()) { 1413 file.mkdir(); 1414 setFilePermissionsFromMode(file.getPath(), mode, 1415 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH); 1416 } 1417 return file; 1418 } 1419 1420 static ContextImpl createSystemContext(ActivityThread mainThread) { 1421 ContextImpl context = new ContextImpl(); 1422 context.init(Resources.getSystem(), mainThread); 1423 return context; 1424 } 1425 1426 ContextImpl() { 1427 mOuterContext = this; 1428 } 1429 1430 /** 1431 * Create a new ApplicationContext from an existing one. The new one 1432 * works and operates the same as the one it is copying. 1433 * 1434 * @param context Existing application context. 1435 */ 1436 public ContextImpl(ContextImpl context) { 1437 mPackageInfo = context.mPackageInfo; 1438 mResources = context.mResources; 1439 mMainThread = context.mMainThread; 1440 mContentResolver = context.mContentResolver; 1441 mOuterContext = this; 1442 } 1443 1444 final void init(LoadedApk packageInfo, 1445 IBinder activityToken, ActivityThread mainThread) { 1446 init(packageInfo, activityToken, mainThread, null); 1447 } 1448 1449 final void init(LoadedApk packageInfo, 1450 IBinder activityToken, ActivityThread mainThread, 1451 Resources container) { 1452 mPackageInfo = packageInfo; 1453 mResources = mPackageInfo.getResources(mainThread); 1454 1455 if (mResources != null && container != null 1456 && container.getCompatibilityInfo().applicationScale != 1457 mResources.getCompatibilityInfo().applicationScale) { 1458 if (DEBUG) { 1459 Log.d(TAG, "loaded context has different scaling. Using container's" + 1460 " compatiblity info:" + container.getDisplayMetrics()); 1461 } 1462 mResources = mainThread.getTopLevelResources( 1463 mPackageInfo.getResDir(), container.getCompatibilityInfo()); 1464 } 1465 mMainThread = mainThread; 1466 mContentResolver = new ApplicationContentResolver(this, mainThread); 1467 1468 setActivityToken(activityToken); 1469 } 1470 1471 final void init(Resources resources, ActivityThread mainThread) { 1472 mPackageInfo = null; 1473 mResources = resources; 1474 mMainThread = mainThread; 1475 mContentResolver = new ApplicationContentResolver(this, mainThread); 1476 } 1477 1478 final void scheduleFinalCleanup(String who, String what) { 1479 mMainThread.scheduleContextCleanup(this, who, what); 1480 } 1481 1482 final void performFinalCleanup(String who, String what) { 1483 //Log.i(TAG, "Cleanup up context: " + this); 1484 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); 1485 } 1486 1487 final Context getReceiverRestrictedContext() { 1488 if (mReceiverRestrictedContext != null) { 1489 return mReceiverRestrictedContext; 1490 } 1491 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext()); 1492 } 1493 1494 final void setActivityToken(IBinder token) { 1495 mActivityToken = token; 1496 } 1497 1498 final void setOuterContext(Context context) { 1499 mOuterContext = context; 1500 } 1501 1502 final Context getOuterContext() { 1503 return mOuterContext; 1504 } 1505 1506 final IBinder getActivityToken() { 1507 return mActivityToken; 1508 } 1509 1510 static void setFilePermissionsFromMode(String name, int mode, 1511 int extraPermissions) { 1512 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR 1513 |FileUtils.S_IRGRP|FileUtils.S_IWGRP 1514 |extraPermissions; 1515 if ((mode&MODE_WORLD_READABLE) != 0) { 1516 perms |= FileUtils.S_IROTH; 1517 } 1518 if ((mode&MODE_WORLD_WRITEABLE) != 0) { 1519 perms |= FileUtils.S_IWOTH; 1520 } 1521 if (DEBUG) { 1522 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode) 1523 + ", perms=0x" + Integer.toHexString(perms)); 1524 } 1525 FileUtils.setPermissions(name, perms, -1, -1); 1526 } 1527 1528 private File validateFilePath(String name, boolean createDirectory) { 1529 File dir; 1530 File f; 1531 1532 if (name.charAt(0) == File.separatorChar) { 1533 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar)); 1534 dir = new File(dirPath); 1535 name = name.substring(name.lastIndexOf(File.separatorChar)); 1536 f = new File(dir, name); 1537 } else { 1538 dir = getDatabasesDir(); 1539 f = makeFilename(dir, name); 1540 } 1541 1542 if (createDirectory && !dir.isDirectory() && dir.mkdir()) { 1543 FileUtils.setPermissions(dir.getPath(), 1544 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 1545 -1, -1); 1546 } 1547 1548 return f; 1549 } 1550 1551 private File makeFilename(File base, String name) { 1552 if (name.indexOf(File.separatorChar) < 0) { 1553 return new File(base, name); 1554 } 1555 throw new IllegalArgumentException( 1556 "File " + name + " contains a path separator"); 1557 } 1558 1559 // ---------------------------------------------------------------------- 1560 // ---------------------------------------------------------------------- 1561 // ---------------------------------------------------------------------- 1562 1563 private static final class ApplicationContentResolver extends ContentResolver { 1564 public ApplicationContentResolver(Context context, ActivityThread mainThread) { 1565 super(context); 1566 mMainThread = mainThread; 1567 } 1568 1569 @Override 1570 protected IContentProvider acquireProvider(Context context, String name) { 1571 return mMainThread.acquireProvider(context, name); 1572 } 1573 1574 @Override 1575 protected IContentProvider acquireExistingProvider(Context context, String name) { 1576 return mMainThread.acquireExistingProvider(context, name); 1577 } 1578 1579 @Override 1580 public boolean releaseProvider(IContentProvider provider) { 1581 return mMainThread.releaseProvider(provider); 1582 } 1583 1584 private final ActivityThread mMainThread; 1585 } 1586} 1587