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