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