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