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