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