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