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