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 import com.android.internal.util.XmlUtils; 21 import com.google.android.collect.Maps; 22 23 import org.xmlpull.v1.XmlPullParserException; 24 25 import android.content.BroadcastReceiver; 26 import android.content.ComponentName; 27 import android.content.ContentResolver; 28 import android.content.Context; 29 import android.content.ContextWrapper; 30 import android.content.IContentProvider; 31 import android.content.Intent; 32 import android.content.IntentFilter; 33 import android.content.IIntentReceiver; 34 import android.content.IntentSender; 35 import android.content.ReceiverCallNotAllowedException; 36 import android.content.ServiceConnection; 37 import android.content.SharedPreferences; 38 import android.content.pm.ActivityInfo; 39 import android.content.pm.ApplicationInfo; 40 import android.content.pm.ComponentInfo; 41 import android.content.pm.FeatureInfo; 42 import android.content.pm.IPackageDataObserver; 43 import android.content.pm.IPackageDeleteObserver; 44 import android.content.pm.IPackageInstallObserver; 45 import android.content.pm.IPackageMoveObserver; 46 import android.content.pm.IPackageManager; 47 import android.content.pm.IPackageStatsObserver; 48 import android.content.pm.InstrumentationInfo; 49 import android.content.pm.PackageInfo; 50 import android.content.pm.PackageManager; 51 import android.content.pm.ParceledListSlice; 52 import android.content.pm.PermissionGroupInfo; 53 import android.content.pm.PermissionInfo; 54 import android.content.pm.ProviderInfo; 55 import android.content.pm.ResolveInfo; 56 import android.content.pm.ServiceInfo; 57 import android.content.pm.PackageParser.Package; 58 import android.content.res.AssetManager; 59 import android.content.res.Resources; 60 import android.content.res.XmlResourceParser; 61 import android.database.sqlite.SQLiteDatabase; 62 import android.database.sqlite.SQLiteDatabase.CursorFactory; 63 import android.graphics.Bitmap; 64 import android.graphics.drawable.Drawable; 65 import android.hardware.SensorManager; 66 import android.hardware.usb.IUsbManager; 67 import android.hardware.usb.UsbManager; 68 import android.location.ILocationManager; 69 import android.location.LocationManager; 70 import android.media.AudioManager; 71 import android.net.ConnectivityManager; 72 import android.net.IConnectivityManager; 73 import android.net.ThrottleManager; 74 import android.net.IThrottleManager; 75 import android.net.Uri; 76 import android.net.wifi.IWifiManager; 77 import android.net.wifi.WifiManager; 78 import android.nfc.NfcManager; 79 import android.os.Binder; 80 import android.os.Bundle; 81 import android.os.DropBoxManager; 82 import android.os.Environment; 83 import android.os.FileUtils; 84 import android.os.Handler; 85 import android.os.IBinder; 86 import android.os.IPowerManager; 87 import android.os.Looper; 88 import android.os.Parcel; 89 import android.os.PowerManager; 90 import android.os.Process; 91 import android.os.RemoteException; 92 import android.os.ServiceManager; 93 import android.os.StatFs; 94 import android.os.Vibrator; 95 import android.os.FileUtils.FileStatus; 96 import android.os.storage.StorageManager; 97 import android.provider.Settings; 98 import android.telephony.TelephonyManager; 99 import android.text.ClipboardManager; 100 import android.util.AndroidRuntimeException; 101 import android.util.Log; 102 import android.view.ContextThemeWrapper; 103 import android.view.LayoutInflater; 104 import android.view.WindowManagerImpl; 105 import android.view.accessibility.AccessibilityManager; 106 import android.view.inputmethod.InputMethodManager; 107 import android.accounts.AccountManager; 108 import android.accounts.IAccountManager; 109 import android.app.admin.DevicePolicyManager; 110 import com.android.internal.os.IDropBoxManagerService; 111 112 import java.io.File; 113 import java.io.FileInputStream; 114 import java.io.FileNotFoundException; 115 import java.io.FileOutputStream; 116 import java.io.IOException; 117 import java.io.InputStream; 118 import java.lang.ref.WeakReference; 119 import java.util.ArrayList; 120 import java.util.HashMap; 121 import java.util.HashSet; 122 import java.util.Iterator; 123 import java.util.List; 124 import java.util.Map; 125 import java.util.Map.Entry; 126 import java.util.Set; 127 import java.util.WeakHashMap; 128 import java.util.concurrent.CountDownLatch; 129 import java.util.concurrent.ExecutorService; 130 131 class ReceiverRestrictedContext extends ContextWrapper { ReceiverRestrictedContext(Context base)132 ReceiverRestrictedContext(Context base) { 133 super(base); 134 } 135 136 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter)137 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 138 return registerReceiver(receiver, filter, null, null); 139 } 140 141 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)142 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 143 String broadcastPermission, Handler scheduler) { 144 throw new ReceiverCallNotAllowedException( 145 "IntentReceiver components are not allowed to register to receive intents"); 146 //ex.fillInStackTrace(); 147 //Log.e("IntentReceiver", ex.getMessage(), ex); 148 //return mContext.registerReceiver(receiver, filter, broadcastPermission, 149 // scheduler); 150 } 151 152 @Override bindService(Intent service, ServiceConnection conn, int flags)153 public boolean bindService(Intent service, ServiceConnection conn, int flags) { 154 throw new ReceiverCallNotAllowedException( 155 "IntentReceiver components are not allowed to bind to services"); 156 //ex.fillInStackTrace(); 157 //Log.e("IntentReceiver", ex.getMessage(), ex); 158 //return mContext.bindService(service, interfaceName, conn, flags); 159 } 160 } 161 162 /** 163 * Common implementation of Context API, which provides the base 164 * context object for Activity and other application components. 165 */ 166 class ContextImpl extends Context { 167 private final static String TAG = "ApplicationContext"; 168 private final static boolean DEBUG = false; 169 private final static boolean DEBUG_ICONS = false; 170 171 private static final Object sSync = new Object(); 172 private static AlarmManager sAlarmManager; 173 private static PowerManager sPowerManager; 174 private static ConnectivityManager sConnectivityManager; 175 private static ThrottleManager sThrottleManager; 176 private static WifiManager sWifiManager; 177 private static LocationManager sLocationManager; 178 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs = 179 new HashMap<String, SharedPreferencesImpl>(); 180 181 private AudioManager mAudioManager; 182 /*package*/ LoadedApk mPackageInfo; 183 private Resources mResources; 184 /*package*/ ActivityThread mMainThread; 185 private Context mOuterContext; 186 private IBinder mActivityToken = null; 187 private ApplicationContentResolver mContentResolver; 188 private int mThemeResource = 0; 189 private Resources.Theme mTheme = null; 190 private PackageManager mPackageManager; 191 private NotificationManager mNotificationManager = null; 192 private ActivityManager mActivityManager = null; 193 private WallpaperManager mWallpaperManager = null; 194 private Context mReceiverRestrictedContext = null; 195 private SearchManager mSearchManager = null; 196 private SensorManager mSensorManager = null; 197 private StorageManager mStorageManager = null; 198 private UsbManager mUsbManager = null; 199 private Vibrator mVibrator = null; 200 private LayoutInflater mLayoutInflater = null; 201 private StatusBarManager mStatusBarManager = null; 202 private TelephonyManager mTelephonyManager = null; 203 private ClipboardManager mClipboardManager = null; 204 private boolean mRestricted; 205 private AccountManager mAccountManager; // protected by mSync 206 private DropBoxManager mDropBoxManager = null; 207 private DevicePolicyManager mDevicePolicyManager = null; 208 private UiModeManager mUiModeManager = null; 209 private DownloadManager mDownloadManager = null; 210 private NfcManager mNfcManager = null; 211 212 private final Object mSync = new Object(); 213 214 private File mDatabasesDir; 215 private File mPreferencesDir; 216 private File mFilesDir; 217 private File mCacheDir; 218 private File mExternalFilesDir; 219 private File mExternalCacheDir; 220 221 private static long sInstanceCount = 0; 222 223 private static final String[] EMPTY_FILE_LIST = {}; 224 225 // For debug only 226 /* 227 @Override 228 protected void finalize() throws Throwable { 229 super.finalize(); 230 --sInstanceCount; 231 } 232 */ 233 getInstanceCount()234 public static long getInstanceCount() { 235 return sInstanceCount; 236 } 237 238 @Override getAssets()239 public AssetManager getAssets() { 240 return mResources.getAssets(); 241 } 242 243 @Override getResources()244 public Resources getResources() { 245 return mResources; 246 } 247 248 @Override getPackageManager()249 public PackageManager getPackageManager() { 250 if (mPackageManager != null) { 251 return mPackageManager; 252 } 253 254 IPackageManager pm = ActivityThread.getPackageManager(); 255 if (pm != null) { 256 // Doesn't matter if we make more than one instance. 257 return (mPackageManager = new ApplicationPackageManager(this, pm)); 258 } 259 260 return null; 261 } 262 263 @Override getContentResolver()264 public ContentResolver getContentResolver() { 265 return mContentResolver; 266 } 267 268 @Override getMainLooper()269 public Looper getMainLooper() { 270 return mMainThread.getLooper(); 271 } 272 273 @Override getApplicationContext()274 public Context getApplicationContext() { 275 return (mPackageInfo != null) ? 276 mPackageInfo.getApplication() : mMainThread.getApplication(); 277 } 278 279 @Override setTheme(int resid)280 public void setTheme(int resid) { 281 mThemeResource = resid; 282 } 283 284 @Override getTheme()285 public Resources.Theme getTheme() { 286 if (mTheme == null) { 287 if (mThemeResource == 0) { 288 mThemeResource = com.android.internal.R.style.Theme; 289 } 290 mTheme = mResources.newTheme(); 291 mTheme.applyStyle(mThemeResource, true); 292 } 293 return mTheme; 294 } 295 296 @Override getClassLoader()297 public ClassLoader getClassLoader() { 298 return mPackageInfo != null ? 299 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader(); 300 } 301 302 @Override getPackageName()303 public String getPackageName() { 304 if (mPackageInfo != null) { 305 return mPackageInfo.getPackageName(); 306 } 307 throw new RuntimeException("Not supported in system context"); 308 } 309 310 @Override getApplicationInfo()311 public ApplicationInfo getApplicationInfo() { 312 if (mPackageInfo != null) { 313 return mPackageInfo.getApplicationInfo(); 314 } 315 throw new RuntimeException("Not supported in system context"); 316 } 317 318 @Override getPackageResourcePath()319 public String getPackageResourcePath() { 320 if (mPackageInfo != null) { 321 return mPackageInfo.getResDir(); 322 } 323 throw new RuntimeException("Not supported in system context"); 324 } 325 326 @Override getPackageCodePath()327 public String getPackageCodePath() { 328 if (mPackageInfo != null) { 329 return mPackageInfo.getAppDir(); 330 } 331 throw new RuntimeException("Not supported in system context"); 332 } 333 makeBackupFile(File prefsFile)334 private static File makeBackupFile(File prefsFile) { 335 return new File(prefsFile.getPath() + ".bak"); 336 } 337 getSharedPrefsFile(String name)338 public File getSharedPrefsFile(String name) { 339 return makeFilename(getPreferencesDir(), name + ".xml"); 340 } 341 342 @Override getSharedPreferences(String name, int mode)343 public SharedPreferences getSharedPreferences(String name, int mode) { 344 SharedPreferencesImpl sp; 345 File prefsFile; 346 boolean needInitialLoad = false; 347 synchronized (sSharedPrefs) { 348 sp = sSharedPrefs.get(name); 349 if (sp != null && !sp.hasFileChangedUnexpectedly()) { 350 return sp; 351 } 352 prefsFile = getSharedPrefsFile(name); 353 if (sp == null) { 354 sp = new SharedPreferencesImpl(prefsFile, mode, null); 355 sSharedPrefs.put(name, sp); 356 needInitialLoad = true; 357 } 358 } 359 360 synchronized (sp) { 361 if (needInitialLoad && sp.isLoaded()) { 362 // lost the race to load; another thread handled it 363 return sp; 364 } 365 File backup = makeBackupFile(prefsFile); 366 if (backup.exists()) { 367 prefsFile.delete(); 368 backup.renameTo(prefsFile); 369 } 370 371 // Debugging 372 if (prefsFile.exists() && !prefsFile.canRead()) { 373 Log.w(TAG, "Attempt to read preferences file " + prefsFile + " without permission"); 374 } 375 376 Map map = null; 377 FileStatus stat = new FileStatus(); 378 if (FileUtils.getFileStatus(prefsFile.getPath(), stat) && prefsFile.canRead()) { 379 try { 380 FileInputStream str = new FileInputStream(prefsFile); 381 map = XmlUtils.readMapXml(str); 382 str.close(); 383 } catch (org.xmlpull.v1.XmlPullParserException e) { 384 Log.w(TAG, "getSharedPreferences", e); 385 } catch (FileNotFoundException e) { 386 Log.w(TAG, "getSharedPreferences", e); 387 } catch (IOException e) { 388 Log.w(TAG, "getSharedPreferences", e); 389 } 390 } 391 sp.replace(map, stat); 392 } 393 return sp; 394 } 395 getPreferencesDir()396 private File getPreferencesDir() { 397 synchronized (mSync) { 398 if (mPreferencesDir == null) { 399 mPreferencesDir = new File(getDataDirFile(), "shared_prefs"); 400 } 401 return mPreferencesDir; 402 } 403 } 404 405 @Override openFileInput(String name)406 public FileInputStream openFileInput(String name) 407 throws FileNotFoundException { 408 File f = makeFilename(getFilesDir(), name); 409 return new FileInputStream(f); 410 } 411 412 @Override openFileOutput(String name, int mode)413 public FileOutputStream openFileOutput(String name, int mode) 414 throws FileNotFoundException { 415 final boolean append = (mode&MODE_APPEND) != 0; 416 File f = makeFilename(getFilesDir(), name); 417 try { 418 FileOutputStream fos = new FileOutputStream(f, append); 419 setFilePermissionsFromMode(f.getPath(), mode, 0); 420 return fos; 421 } catch (FileNotFoundException e) { 422 } 423 424 File parent = f.getParentFile(); 425 parent.mkdir(); 426 FileUtils.setPermissions( 427 parent.getPath(), 428 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 429 -1, -1); 430 FileOutputStream fos = new FileOutputStream(f, append); 431 setFilePermissionsFromMode(f.getPath(), mode, 0); 432 return fos; 433 } 434 435 @Override deleteFile(String name)436 public boolean deleteFile(String name) { 437 File f = makeFilename(getFilesDir(), name); 438 return f.delete(); 439 } 440 441 @Override getFilesDir()442 public File getFilesDir() { 443 synchronized (mSync) { 444 if (mFilesDir == null) { 445 mFilesDir = new File(getDataDirFile(), "files"); 446 } 447 if (!mFilesDir.exists()) { 448 if(!mFilesDir.mkdirs()) { 449 Log.w(TAG, "Unable to create files directory"); 450 return null; 451 } 452 FileUtils.setPermissions( 453 mFilesDir.getPath(), 454 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 455 -1, -1); 456 } 457 return mFilesDir; 458 } 459 } 460 461 @Override getExternalFilesDir(String type)462 public File getExternalFilesDir(String type) { 463 synchronized (mSync) { 464 if (mExternalFilesDir == null) { 465 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory( 466 getPackageName()); 467 } 468 if (!mExternalFilesDir.exists()) { 469 try { 470 (new File(Environment.getExternalStorageAndroidDataDir(), 471 ".nomedia")).createNewFile(); 472 } catch (IOException e) { 473 } 474 if (!mExternalFilesDir.mkdirs()) { 475 Log.w(TAG, "Unable to create external files directory"); 476 return null; 477 } 478 } 479 if (type == null) { 480 return mExternalFilesDir; 481 } 482 File dir = new File(mExternalFilesDir, type); 483 if (!dir.exists()) { 484 if (!dir.mkdirs()) { 485 Log.w(TAG, "Unable to create external media directory " + dir); 486 return null; 487 } 488 } 489 return dir; 490 } 491 } 492 493 @Override getCacheDir()494 public File getCacheDir() { 495 synchronized (mSync) { 496 if (mCacheDir == null) { 497 mCacheDir = new File(getDataDirFile(), "cache"); 498 } 499 if (!mCacheDir.exists()) { 500 if(!mCacheDir.mkdirs()) { 501 Log.w(TAG, "Unable to create cache directory"); 502 return null; 503 } 504 FileUtils.setPermissions( 505 mCacheDir.getPath(), 506 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 507 -1, -1); 508 } 509 } 510 return mCacheDir; 511 } 512 513 @Override getExternalCacheDir()514 public File getExternalCacheDir() { 515 synchronized (mSync) { 516 if (mExternalCacheDir == null) { 517 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory( 518 getPackageName()); 519 } 520 if (!mExternalCacheDir.exists()) { 521 try { 522 (new File(Environment.getExternalStorageAndroidDataDir(), 523 ".nomedia")).createNewFile(); 524 } catch (IOException e) { 525 } 526 if (!mExternalCacheDir.mkdirs()) { 527 Log.w(TAG, "Unable to create external cache directory"); 528 return null; 529 } 530 } 531 return mExternalCacheDir; 532 } 533 } 534 535 @Override getFileStreamPath(String name)536 public File getFileStreamPath(String name) { 537 return makeFilename(getFilesDir(), name); 538 } 539 540 @Override fileList()541 public String[] fileList() { 542 final String[] list = getFilesDir().list(); 543 return (list != null) ? list : EMPTY_FILE_LIST; 544 } 545 546 @Override openOrCreateDatabase(String name, int mode, CursorFactory factory)547 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) { 548 File f = validateFilePath(name, true); 549 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory); 550 setFilePermissionsFromMode(f.getPath(), mode, 0); 551 return db; 552 } 553 554 @Override deleteDatabase(String name)555 public boolean deleteDatabase(String name) { 556 try { 557 File f = validateFilePath(name, false); 558 return f.delete(); 559 } catch (Exception e) { 560 } 561 return false; 562 } 563 564 @Override getDatabasePath(String name)565 public File getDatabasePath(String name) { 566 return validateFilePath(name, false); 567 } 568 569 @Override databaseList()570 public String[] databaseList() { 571 final String[] list = getDatabasesDir().list(); 572 return (list != null) ? list : EMPTY_FILE_LIST; 573 } 574 575 getDatabasesDir()576 private File getDatabasesDir() { 577 synchronized (mSync) { 578 if (mDatabasesDir == null) { 579 mDatabasesDir = new File(getDataDirFile(), "databases"); 580 } 581 if (mDatabasesDir.getPath().equals("databases")) { 582 mDatabasesDir = new File("/data/system"); 583 } 584 return mDatabasesDir; 585 } 586 } 587 588 @Override getWallpaper()589 public Drawable getWallpaper() { 590 return getWallpaperManager().getDrawable(); 591 } 592 593 @Override peekWallpaper()594 public Drawable peekWallpaper() { 595 return getWallpaperManager().peekDrawable(); 596 } 597 598 @Override getWallpaperDesiredMinimumWidth()599 public int getWallpaperDesiredMinimumWidth() { 600 return getWallpaperManager().getDesiredMinimumWidth(); 601 } 602 603 @Override getWallpaperDesiredMinimumHeight()604 public int getWallpaperDesiredMinimumHeight() { 605 return getWallpaperManager().getDesiredMinimumHeight(); 606 } 607 608 @Override setWallpaper(Bitmap bitmap)609 public void setWallpaper(Bitmap bitmap) throws IOException { 610 getWallpaperManager().setBitmap(bitmap); 611 } 612 613 @Override setWallpaper(InputStream data)614 public void setWallpaper(InputStream data) throws IOException { 615 getWallpaperManager().setStream(data); 616 } 617 618 @Override clearWallpaper()619 public void clearWallpaper() throws IOException { 620 getWallpaperManager().clear(); 621 } 622 623 @Override startActivity(Intent intent)624 public void startActivity(Intent intent) { 625 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 626 throw new AndroidRuntimeException( 627 "Calling startActivity() from outside of an Activity " 628 + " context requires the FLAG_ACTIVITY_NEW_TASK flag." 629 + " Is this really what you want?"); 630 } 631 mMainThread.getInstrumentation().execStartActivity( 632 getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1); 633 } 634 635 @Override startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)636 public void startIntentSender(IntentSender intent, 637 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 638 throws IntentSender.SendIntentException { 639 try { 640 String resolvedType = null; 641 if (fillInIntent != null) { 642 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 643 } 644 int result = ActivityManagerNative.getDefault() 645 .startActivityIntentSender(mMainThread.getApplicationThread(), intent, 646 fillInIntent, resolvedType, null, null, 647 0, flagsMask, flagsValues); 648 if (result == IActivityManager.START_CANCELED) { 649 throw new IntentSender.SendIntentException(); 650 } 651 Instrumentation.checkStartActivityResult(result, null); 652 } catch (RemoteException e) { 653 } 654 } 655 656 @Override sendBroadcast(Intent intent)657 public void sendBroadcast(Intent intent) { 658 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 659 try { 660 ActivityManagerNative.getDefault().broadcastIntent( 661 mMainThread.getApplicationThread(), intent, resolvedType, null, 662 Activity.RESULT_OK, null, null, null, false, false); 663 } catch (RemoteException e) { 664 } 665 } 666 667 @Override sendBroadcast(Intent intent, String receiverPermission)668 public void sendBroadcast(Intent intent, String receiverPermission) { 669 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 670 try { 671 ActivityManagerNative.getDefault().broadcastIntent( 672 mMainThread.getApplicationThread(), intent, resolvedType, null, 673 Activity.RESULT_OK, null, null, receiverPermission, false, false); 674 } catch (RemoteException e) { 675 } 676 } 677 678 @Override sendOrderedBroadcast(Intent intent, String receiverPermission)679 public void sendOrderedBroadcast(Intent intent, 680 String receiverPermission) { 681 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 682 try { 683 ActivityManagerNative.getDefault().broadcastIntent( 684 mMainThread.getApplicationThread(), intent, resolvedType, null, 685 Activity.RESULT_OK, null, null, receiverPermission, true, false); 686 } catch (RemoteException e) { 687 } 688 } 689 690 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)691 public void sendOrderedBroadcast(Intent intent, 692 String receiverPermission, BroadcastReceiver resultReceiver, 693 Handler scheduler, int initialCode, String initialData, 694 Bundle initialExtras) { 695 IIntentReceiver rd = null; 696 if (resultReceiver != null) { 697 if (mPackageInfo != null) { 698 if (scheduler == null) { 699 scheduler = mMainThread.getHandler(); 700 } 701 rd = mPackageInfo.getReceiverDispatcher( 702 resultReceiver, getOuterContext(), scheduler, 703 mMainThread.getInstrumentation(), false); 704 } else { 705 if (scheduler == null) { 706 scheduler = mMainThread.getHandler(); 707 } 708 rd = new LoadedApk.ReceiverDispatcher( 709 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 710 } 711 } 712 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 713 try { 714 ActivityManagerNative.getDefault().broadcastIntent( 715 mMainThread.getApplicationThread(), intent, resolvedType, rd, 716 initialCode, initialData, initialExtras, receiverPermission, 717 true, false); 718 } catch (RemoteException e) { 719 } 720 } 721 722 @Override sendStickyBroadcast(Intent intent)723 public void sendStickyBroadcast(Intent intent) { 724 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 725 try { 726 ActivityManagerNative.getDefault().broadcastIntent( 727 mMainThread.getApplicationThread(), intent, resolvedType, null, 728 Activity.RESULT_OK, null, null, null, false, true); 729 } catch (RemoteException e) { 730 } 731 } 732 733 @Override sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)734 public void sendStickyOrderedBroadcast(Intent intent, 735 BroadcastReceiver resultReceiver, 736 Handler scheduler, int initialCode, String initialData, 737 Bundle initialExtras) { 738 IIntentReceiver rd = null; 739 if (resultReceiver != null) { 740 if (mPackageInfo != null) { 741 if (scheduler == null) { 742 scheduler = mMainThread.getHandler(); 743 } 744 rd = mPackageInfo.getReceiverDispatcher( 745 resultReceiver, getOuterContext(), scheduler, 746 mMainThread.getInstrumentation(), false); 747 } else { 748 if (scheduler == null) { 749 scheduler = mMainThread.getHandler(); 750 } 751 rd = new LoadedApk.ReceiverDispatcher( 752 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 753 } 754 } 755 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 756 try { 757 ActivityManagerNative.getDefault().broadcastIntent( 758 mMainThread.getApplicationThread(), intent, resolvedType, rd, 759 initialCode, initialData, initialExtras, null, 760 true, true); 761 } catch (RemoteException e) { 762 } 763 } 764 765 @Override removeStickyBroadcast(Intent intent)766 public void removeStickyBroadcast(Intent intent) { 767 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 768 if (resolvedType != null) { 769 intent = new Intent(intent); 770 intent.setDataAndType(intent.getData(), resolvedType); 771 } 772 try { 773 ActivityManagerNative.getDefault().unbroadcastIntent( 774 mMainThread.getApplicationThread(), intent); 775 } catch (RemoteException e) { 776 } 777 } 778 779 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter)780 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 781 return registerReceiver(receiver, filter, null, null); 782 } 783 784 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)785 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 786 String broadcastPermission, Handler scheduler) { 787 return registerReceiverInternal(receiver, filter, broadcastPermission, 788 scheduler, getOuterContext()); 789 } 790 registerReceiverInternal(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context)791 private Intent registerReceiverInternal(BroadcastReceiver receiver, 792 IntentFilter filter, String broadcastPermission, 793 Handler scheduler, Context context) { 794 IIntentReceiver rd = null; 795 if (receiver != null) { 796 if (mPackageInfo != null && context != null) { 797 if (scheduler == null) { 798 scheduler = mMainThread.getHandler(); 799 } 800 rd = mPackageInfo.getReceiverDispatcher( 801 receiver, context, scheduler, 802 mMainThread.getInstrumentation(), true); 803 } else { 804 if (scheduler == null) { 805 scheduler = mMainThread.getHandler(); 806 } 807 rd = new LoadedApk.ReceiverDispatcher( 808 receiver, context, scheduler, null, true).getIIntentReceiver(); 809 } 810 } 811 try { 812 return ActivityManagerNative.getDefault().registerReceiver( 813 mMainThread.getApplicationThread(), 814 rd, filter, broadcastPermission); 815 } catch (RemoteException e) { 816 return null; 817 } 818 } 819 820 @Override unregisterReceiver(BroadcastReceiver receiver)821 public void unregisterReceiver(BroadcastReceiver receiver) { 822 if (mPackageInfo != null) { 823 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( 824 getOuterContext(), receiver); 825 try { 826 ActivityManagerNative.getDefault().unregisterReceiver(rd); 827 } catch (RemoteException e) { 828 } 829 } else { 830 throw new RuntimeException("Not supported in system context"); 831 } 832 } 833 834 @Override startService(Intent service)835 public ComponentName startService(Intent service) { 836 try { 837 ComponentName cn = ActivityManagerNative.getDefault().startService( 838 mMainThread.getApplicationThread(), service, 839 service.resolveTypeIfNeeded(getContentResolver())); 840 if (cn != null && cn.getPackageName().equals("!")) { 841 throw new SecurityException( 842 "Not allowed to start service " + service 843 + " without permission " + cn.getClassName()); 844 } 845 return cn; 846 } catch (RemoteException e) { 847 return null; 848 } 849 } 850 851 @Override stopService(Intent service)852 public boolean stopService(Intent service) { 853 try { 854 int res = ActivityManagerNative.getDefault().stopService( 855 mMainThread.getApplicationThread(), service, 856 service.resolveTypeIfNeeded(getContentResolver())); 857 if (res < 0) { 858 throw new SecurityException( 859 "Not allowed to stop service " + service); 860 } 861 return res != 0; 862 } catch (RemoteException e) { 863 return false; 864 } 865 } 866 867 @Override bindService(Intent service, ServiceConnection conn, int flags)868 public boolean bindService(Intent service, ServiceConnection conn, 869 int flags) { 870 IServiceConnection sd; 871 if (mPackageInfo != null) { 872 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), 873 mMainThread.getHandler(), flags); 874 } else { 875 throw new RuntimeException("Not supported in system context"); 876 } 877 try { 878 int res = ActivityManagerNative.getDefault().bindService( 879 mMainThread.getApplicationThread(), getActivityToken(), 880 service, service.resolveTypeIfNeeded(getContentResolver()), 881 sd, flags); 882 if (res < 0) { 883 throw new SecurityException( 884 "Not allowed to bind to service " + service); 885 } 886 return res != 0; 887 } catch (RemoteException e) { 888 return false; 889 } 890 } 891 892 @Override unbindService(ServiceConnection conn)893 public void unbindService(ServiceConnection conn) { 894 if (mPackageInfo != null) { 895 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( 896 getOuterContext(), conn); 897 try { 898 ActivityManagerNative.getDefault().unbindService(sd); 899 } catch (RemoteException e) { 900 } 901 } else { 902 throw new RuntimeException("Not supported in system context"); 903 } 904 } 905 906 @Override startInstrumentation(ComponentName className, String profileFile, Bundle arguments)907 public boolean startInstrumentation(ComponentName className, 908 String profileFile, Bundle arguments) { 909 try { 910 return ActivityManagerNative.getDefault().startInstrumentation( 911 className, profileFile, 0, arguments, null); 912 } catch (RemoteException e) { 913 // System has crashed, nothing we can do. 914 } 915 return false; 916 } 917 918 @Override getSystemService(String name)919 public Object getSystemService(String name) { 920 if (WINDOW_SERVICE.equals(name)) { 921 return WindowManagerImpl.getDefault(); 922 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) { 923 synchronized (mSync) { 924 LayoutInflater inflater = mLayoutInflater; 925 if (inflater != null) { 926 return inflater; 927 } 928 mLayoutInflater = inflater = 929 PolicyManager.makeNewLayoutInflater(getOuterContext()); 930 return inflater; 931 } 932 } else if (ACTIVITY_SERVICE.equals(name)) { 933 return getActivityManager(); 934 } else if (INPUT_METHOD_SERVICE.equals(name)) { 935 return InputMethodManager.getInstance(this); 936 } else if (ALARM_SERVICE.equals(name)) { 937 return getAlarmManager(); 938 } else if (ACCOUNT_SERVICE.equals(name)) { 939 return getAccountManager(); 940 } else if (POWER_SERVICE.equals(name)) { 941 return getPowerManager(); 942 } else if (CONNECTIVITY_SERVICE.equals(name)) { 943 return getConnectivityManager(); 944 } else if (THROTTLE_SERVICE.equals(name)) { 945 return getThrottleManager(); 946 } else if (WIFI_SERVICE.equals(name)) { 947 return getWifiManager(); 948 } else if (NOTIFICATION_SERVICE.equals(name)) { 949 return getNotificationManager(); 950 } else if (KEYGUARD_SERVICE.equals(name)) { 951 return new KeyguardManager(); 952 } else if (ACCESSIBILITY_SERVICE.equals(name)) { 953 return AccessibilityManager.getInstance(this); 954 } else if (LOCATION_SERVICE.equals(name)) { 955 return getLocationManager(); 956 } else if (SEARCH_SERVICE.equals(name)) { 957 return getSearchManager(); 958 } else if (SENSOR_SERVICE.equals(name)) { 959 return getSensorManager(); 960 } else if (STORAGE_SERVICE.equals(name)) { 961 return getStorageManager(); 962 } else if (USB_SERVICE.equals(name)) { 963 return getUsbManager(); 964 } else if (VIBRATOR_SERVICE.equals(name)) { 965 return getVibrator(); 966 } else if (STATUS_BAR_SERVICE.equals(name)) { 967 synchronized (mSync) { 968 if (mStatusBarManager == null) { 969 mStatusBarManager = new StatusBarManager(getOuterContext()); 970 } 971 return mStatusBarManager; 972 } 973 } else if (AUDIO_SERVICE.equals(name)) { 974 return getAudioManager(); 975 } else if (TELEPHONY_SERVICE.equals(name)) { 976 return getTelephonyManager(); 977 } else if (CLIPBOARD_SERVICE.equals(name)) { 978 return getClipboardManager(); 979 } else if (WALLPAPER_SERVICE.equals(name)) { 980 return getWallpaperManager(); 981 } else if (DROPBOX_SERVICE.equals(name)) { 982 return getDropBoxManager(); 983 } else if (DEVICE_POLICY_SERVICE.equals(name)) { 984 return getDevicePolicyManager(); 985 } else if (UI_MODE_SERVICE.equals(name)) { 986 return getUiModeManager(); 987 } else if (DOWNLOAD_SERVICE.equals(name)) { 988 return getDownloadManager(); 989 } else if (NFC_SERVICE.equals(name)) { 990 return getNfcManager(); 991 } 992 993 return null; 994 } 995 getAccountManager()996 private AccountManager getAccountManager() { 997 synchronized (mSync) { 998 if (mAccountManager == null) { 999 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE); 1000 IAccountManager service = IAccountManager.Stub.asInterface(b); 1001 mAccountManager = new AccountManager(this, service); 1002 } 1003 return mAccountManager; 1004 } 1005 } 1006 getActivityManager()1007 private ActivityManager getActivityManager() { 1008 synchronized (mSync) { 1009 if (mActivityManager == null) { 1010 mActivityManager = new ActivityManager(getOuterContext(), 1011 mMainThread.getHandler()); 1012 } 1013 } 1014 return mActivityManager; 1015 } 1016 getAlarmManager()1017 private AlarmManager getAlarmManager() { 1018 synchronized (sSync) { 1019 if (sAlarmManager == null) { 1020 IBinder b = ServiceManager.getService(ALARM_SERVICE); 1021 IAlarmManager service = IAlarmManager.Stub.asInterface(b); 1022 sAlarmManager = new AlarmManager(service); 1023 } 1024 } 1025 return sAlarmManager; 1026 } 1027 getPowerManager()1028 private PowerManager getPowerManager() { 1029 synchronized (sSync) { 1030 if (sPowerManager == null) { 1031 IBinder b = ServiceManager.getService(POWER_SERVICE); 1032 IPowerManager service = IPowerManager.Stub.asInterface(b); 1033 sPowerManager = new PowerManager(service, mMainThread.getHandler()); 1034 } 1035 } 1036 return sPowerManager; 1037 } 1038 getConnectivityManager()1039 private ConnectivityManager getConnectivityManager() 1040 { 1041 synchronized (sSync) { 1042 if (sConnectivityManager == null) { 1043 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE); 1044 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 1045 sConnectivityManager = new ConnectivityManager(service); 1046 } 1047 } 1048 return sConnectivityManager; 1049 } 1050 getThrottleManager()1051 private ThrottleManager getThrottleManager() 1052 { 1053 synchronized (sSync) { 1054 if (sThrottleManager == null) { 1055 IBinder b = ServiceManager.getService(THROTTLE_SERVICE); 1056 IThrottleManager service = IThrottleManager.Stub.asInterface(b); 1057 sThrottleManager = new ThrottleManager(service); 1058 } 1059 } 1060 return sThrottleManager; 1061 } 1062 getWifiManager()1063 private WifiManager getWifiManager() 1064 { 1065 synchronized (sSync) { 1066 if (sWifiManager == null) { 1067 IBinder b = ServiceManager.getService(WIFI_SERVICE); 1068 IWifiManager service = IWifiManager.Stub.asInterface(b); 1069 sWifiManager = new WifiManager(service, mMainThread.getHandler()); 1070 } 1071 } 1072 return sWifiManager; 1073 } 1074 getNotificationManager()1075 private NotificationManager getNotificationManager() { 1076 synchronized (mSync) { 1077 if (mNotificationManager == null) { 1078 mNotificationManager = new NotificationManager( 1079 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog), 1080 mMainThread.getHandler()); 1081 } 1082 } 1083 return mNotificationManager; 1084 } 1085 getWallpaperManager()1086 private WallpaperManager getWallpaperManager() { 1087 synchronized (mSync) { 1088 if (mWallpaperManager == null) { 1089 mWallpaperManager = new WallpaperManager(getOuterContext(), 1090 mMainThread.getHandler()); 1091 } 1092 } 1093 return mWallpaperManager; 1094 } 1095 getTelephonyManager()1096 private TelephonyManager getTelephonyManager() { 1097 synchronized (mSync) { 1098 if (mTelephonyManager == null) { 1099 mTelephonyManager = new TelephonyManager(getOuterContext()); 1100 } 1101 } 1102 return mTelephonyManager; 1103 } 1104 getClipboardManager()1105 private ClipboardManager getClipboardManager() { 1106 synchronized (mSync) { 1107 if (mClipboardManager == null) { 1108 mClipboardManager = new ClipboardManager(getOuterContext(), 1109 mMainThread.getHandler()); 1110 } 1111 } 1112 return mClipboardManager; 1113 } 1114 getLocationManager()1115 private LocationManager getLocationManager() { 1116 synchronized (sSync) { 1117 if (sLocationManager == null) { 1118 IBinder b = ServiceManager.getService(LOCATION_SERVICE); 1119 ILocationManager service = ILocationManager.Stub.asInterface(b); 1120 sLocationManager = new LocationManager(service); 1121 } 1122 } 1123 return sLocationManager; 1124 } 1125 getSearchManager()1126 private SearchManager getSearchManager() { 1127 synchronized (mSync) { 1128 if (mSearchManager == null) { 1129 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler()); 1130 } 1131 } 1132 return mSearchManager; 1133 } 1134 getSensorManager()1135 private SensorManager getSensorManager() { 1136 synchronized (mSync) { 1137 if (mSensorManager == null) { 1138 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper()); 1139 } 1140 } 1141 return mSensorManager; 1142 } 1143 getStorageManager()1144 private StorageManager getStorageManager() { 1145 synchronized (mSync) { 1146 if (mStorageManager == null) { 1147 try { 1148 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper()); 1149 } catch (RemoteException rex) { 1150 Log.e(TAG, "Failed to create StorageManager", rex); 1151 mStorageManager = null; 1152 } 1153 } 1154 } 1155 return mStorageManager; 1156 } 1157 getUsbManager()1158 private UsbManager getUsbManager() { 1159 synchronized (mSync) { 1160 if (mUsbManager == null) { 1161 IBinder b = ServiceManager.getService(USB_SERVICE); 1162 IUsbManager service = IUsbManager.Stub.asInterface(b); 1163 mUsbManager = new UsbManager(this, service); 1164 } 1165 } 1166 return mUsbManager; 1167 } 1168 getVibrator()1169 private Vibrator getVibrator() { 1170 synchronized (mSync) { 1171 if (mVibrator == null) { 1172 mVibrator = new Vibrator(); 1173 } 1174 } 1175 return mVibrator; 1176 } 1177 getAudioManager()1178 private AudioManager getAudioManager() 1179 { 1180 if (mAudioManager == null) { 1181 mAudioManager = new AudioManager(this); 1182 } 1183 return mAudioManager; 1184 } 1185 createDropBoxManager()1186 /* package */ static DropBoxManager createDropBoxManager() { 1187 IBinder b = ServiceManager.getService(DROPBOX_SERVICE); 1188 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b); 1189 return new DropBoxManager(service); 1190 } 1191 getDropBoxManager()1192 private DropBoxManager getDropBoxManager() { 1193 synchronized (mSync) { 1194 if (mDropBoxManager == null) { 1195 mDropBoxManager = createDropBoxManager(); 1196 } 1197 } 1198 return mDropBoxManager; 1199 } 1200 getDevicePolicyManager()1201 private DevicePolicyManager getDevicePolicyManager() { 1202 synchronized (mSync) { 1203 if (mDevicePolicyManager == null) { 1204 mDevicePolicyManager = DevicePolicyManager.create(this, 1205 mMainThread.getHandler()); 1206 } 1207 } 1208 return mDevicePolicyManager; 1209 } 1210 getUiModeManager()1211 private UiModeManager getUiModeManager() { 1212 synchronized (mSync) { 1213 if (mUiModeManager == null) { 1214 mUiModeManager = new UiModeManager(); 1215 } 1216 } 1217 return mUiModeManager; 1218 } 1219 getDownloadManager()1220 private DownloadManager getDownloadManager() { 1221 synchronized (mSync) { 1222 if (mDownloadManager == null) { 1223 mDownloadManager = new DownloadManager(getContentResolver(), getPackageName()); 1224 } 1225 } 1226 return mDownloadManager; 1227 } 1228 getNfcManager()1229 private NfcManager getNfcManager() { 1230 synchronized (mSync) { 1231 if (mNfcManager == null) { 1232 mNfcManager = new NfcManager(this); 1233 } 1234 } 1235 return mNfcManager; 1236 } 1237 1238 @Override checkPermission(String permission, int pid, int uid)1239 public int checkPermission(String permission, int pid, int uid) { 1240 if (permission == null) { 1241 throw new IllegalArgumentException("permission is null"); 1242 } 1243 1244 if (!Process.supportsProcesses()) { 1245 return PackageManager.PERMISSION_GRANTED; 1246 } 1247 try { 1248 return ActivityManagerNative.getDefault().checkPermission( 1249 permission, pid, uid); 1250 } catch (RemoteException e) { 1251 return PackageManager.PERMISSION_DENIED; 1252 } 1253 } 1254 1255 @Override checkCallingPermission(String permission)1256 public int checkCallingPermission(String permission) { 1257 if (permission == null) { 1258 throw new IllegalArgumentException("permission is null"); 1259 } 1260 1261 if (!Process.supportsProcesses()) { 1262 return PackageManager.PERMISSION_GRANTED; 1263 } 1264 int pid = Binder.getCallingPid(); 1265 if (pid != Process.myPid()) { 1266 return checkPermission(permission, pid, 1267 Binder.getCallingUid()); 1268 } 1269 return PackageManager.PERMISSION_DENIED; 1270 } 1271 1272 @Override checkCallingOrSelfPermission(String permission)1273 public int checkCallingOrSelfPermission(String permission) { 1274 if (permission == null) { 1275 throw new IllegalArgumentException("permission is null"); 1276 } 1277 1278 return checkPermission(permission, Binder.getCallingPid(), 1279 Binder.getCallingUid()); 1280 } 1281 enforce( String permission, int resultOfCheck, boolean selfToo, int uid, String message)1282 private void enforce( 1283 String permission, int resultOfCheck, 1284 boolean selfToo, int uid, String message) { 1285 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1286 throw new SecurityException( 1287 (message != null ? (message + ": ") : "") + 1288 (selfToo 1289 ? "Neither user " + uid + " nor current process has " 1290 : "User " + uid + " does not have ") + 1291 permission + 1292 "."); 1293 } 1294 } 1295 enforcePermission( String permission, int pid, int uid, String message)1296 public void enforcePermission( 1297 String permission, int pid, int uid, String message) { 1298 enforce(permission, 1299 checkPermission(permission, pid, uid), 1300 false, 1301 uid, 1302 message); 1303 } 1304 enforceCallingPermission(String permission, String message)1305 public void enforceCallingPermission(String permission, String message) { 1306 enforce(permission, 1307 checkCallingPermission(permission), 1308 false, 1309 Binder.getCallingUid(), 1310 message); 1311 } 1312 enforceCallingOrSelfPermission( String permission, String message)1313 public void enforceCallingOrSelfPermission( 1314 String permission, String message) { 1315 enforce(permission, 1316 checkCallingOrSelfPermission(permission), 1317 true, 1318 Binder.getCallingUid(), 1319 message); 1320 } 1321 1322 @Override grantUriPermission(String toPackage, Uri uri, int modeFlags)1323 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) { 1324 try { 1325 ActivityManagerNative.getDefault().grantUriPermission( 1326 mMainThread.getApplicationThread(), toPackage, uri, 1327 modeFlags); 1328 } catch (RemoteException e) { 1329 } 1330 } 1331 1332 @Override revokeUriPermission(Uri uri, int modeFlags)1333 public void revokeUriPermission(Uri uri, int modeFlags) { 1334 try { 1335 ActivityManagerNative.getDefault().revokeUriPermission( 1336 mMainThread.getApplicationThread(), uri, 1337 modeFlags); 1338 } catch (RemoteException e) { 1339 } 1340 } 1341 1342 @Override checkUriPermission(Uri uri, int pid, int uid, int modeFlags)1343 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 1344 if (!Process.supportsProcesses()) { 1345 return PackageManager.PERMISSION_GRANTED; 1346 } 1347 try { 1348 return ActivityManagerNative.getDefault().checkUriPermission( 1349 uri, pid, uid, modeFlags); 1350 } catch (RemoteException e) { 1351 return PackageManager.PERMISSION_DENIED; 1352 } 1353 } 1354 1355 @Override checkCallingUriPermission(Uri uri, int modeFlags)1356 public int checkCallingUriPermission(Uri uri, int modeFlags) { 1357 if (!Process.supportsProcesses()) { 1358 return PackageManager.PERMISSION_GRANTED; 1359 } 1360 int pid = Binder.getCallingPid(); 1361 if (pid != Process.myPid()) { 1362 return checkUriPermission(uri, pid, 1363 Binder.getCallingUid(), modeFlags); 1364 } 1365 return PackageManager.PERMISSION_DENIED; 1366 } 1367 1368 @Override checkCallingOrSelfUriPermission(Uri uri, int modeFlags)1369 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) { 1370 return checkUriPermission(uri, Binder.getCallingPid(), 1371 Binder.getCallingUid(), modeFlags); 1372 } 1373 1374 @Override checkUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags)1375 public int checkUriPermission(Uri uri, String readPermission, 1376 String writePermission, int pid, int uid, int modeFlags) { 1377 if (DEBUG) { 1378 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission=" 1379 + readPermission + " writePermission=" + writePermission 1380 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags); 1381 } 1382 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 1383 if (readPermission == null 1384 || checkPermission(readPermission, pid, uid) 1385 == PackageManager.PERMISSION_GRANTED) { 1386 return PackageManager.PERMISSION_GRANTED; 1387 } 1388 } 1389 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 1390 if (writePermission == null 1391 || checkPermission(writePermission, pid, uid) 1392 == PackageManager.PERMISSION_GRANTED) { 1393 return PackageManager.PERMISSION_GRANTED; 1394 } 1395 } 1396 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags) 1397 : PackageManager.PERMISSION_DENIED; 1398 } 1399 uriModeFlagToString(int uriModeFlags)1400 private String uriModeFlagToString(int uriModeFlags) { 1401 switch (uriModeFlags) { 1402 case Intent.FLAG_GRANT_READ_URI_PERMISSION | 1403 Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1404 return "read and write"; 1405 case Intent.FLAG_GRANT_READ_URI_PERMISSION: 1406 return "read"; 1407 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1408 return "write"; 1409 } 1410 throw new IllegalArgumentException( 1411 "Unknown permission mode flags: " + uriModeFlags); 1412 } 1413 enforceForUri( int modeFlags, int resultOfCheck, boolean selfToo, int uid, Uri uri, String message)1414 private void enforceForUri( 1415 int modeFlags, int resultOfCheck, boolean selfToo, 1416 int uid, Uri uri, String message) { 1417 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1418 throw new SecurityException( 1419 (message != null ? (message + ": ") : "") + 1420 (selfToo 1421 ? "Neither user " + uid + " nor current process has " 1422 : "User " + uid + " does not have ") + 1423 uriModeFlagToString(modeFlags) + 1424 " permission on " + 1425 uri + 1426 "."); 1427 } 1428 } 1429 enforceUriPermission( Uri uri, int pid, int uid, int modeFlags, String message)1430 public void enforceUriPermission( 1431 Uri uri, int pid, int uid, int modeFlags, String message) { 1432 enforceForUri( 1433 modeFlags, checkUriPermission(uri, pid, uid, modeFlags), 1434 false, uid, uri, message); 1435 } 1436 enforceCallingUriPermission( Uri uri, int modeFlags, String message)1437 public void enforceCallingUriPermission( 1438 Uri uri, int modeFlags, String message) { 1439 enforceForUri( 1440 modeFlags, checkCallingUriPermission(uri, modeFlags), 1441 false, Binder.getCallingUid(), uri, message); 1442 } 1443 enforceCallingOrSelfUriPermission( Uri uri, int modeFlags, String message)1444 public void enforceCallingOrSelfUriPermission( 1445 Uri uri, int modeFlags, String message) { 1446 enforceForUri( 1447 modeFlags, 1448 checkCallingOrSelfUriPermission(uri, modeFlags), true, 1449 Binder.getCallingUid(), uri, message); 1450 } 1451 enforceUriPermission( Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags, String message)1452 public void enforceUriPermission( 1453 Uri uri, String readPermission, String writePermission, 1454 int pid, int uid, int modeFlags, String message) { 1455 enforceForUri(modeFlags, 1456 checkUriPermission( 1457 uri, readPermission, writePermission, pid, uid, 1458 modeFlags), 1459 false, 1460 uid, 1461 uri, 1462 message); 1463 } 1464 1465 @Override createPackageContext(String packageName, int flags)1466 public Context createPackageContext(String packageName, int flags) 1467 throws PackageManager.NameNotFoundException { 1468 if (packageName.equals("system") || packageName.equals("android")) { 1469 return new ContextImpl(mMainThread.getSystemContext()); 1470 } 1471 1472 LoadedApk pi = 1473 mMainThread.getPackageInfo(packageName, flags); 1474 if (pi != null) { 1475 ContextImpl c = new ContextImpl(); 1476 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; 1477 c.init(pi, null, mMainThread, mResources); 1478 if (c.mResources != null) { 1479 return c; 1480 } 1481 } 1482 1483 // Should be a better exception. 1484 throw new PackageManager.NameNotFoundException( 1485 "Application package " + packageName + " not found"); 1486 } 1487 1488 @Override isRestricted()1489 public boolean isRestricted() { 1490 return mRestricted; 1491 } 1492 getDataDirFile()1493 private File getDataDirFile() { 1494 if (mPackageInfo != null) { 1495 return mPackageInfo.getDataDirFile(); 1496 } 1497 throw new RuntimeException("Not supported in system context"); 1498 } 1499 1500 @Override getDir(String name, int mode)1501 public File getDir(String name, int mode) { 1502 name = "app_" + name; 1503 File file = makeFilename(getDataDirFile(), name); 1504 if (!file.exists()) { 1505 file.mkdir(); 1506 setFilePermissionsFromMode(file.getPath(), mode, 1507 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH); 1508 } 1509 return file; 1510 } 1511 createSystemContext(ActivityThread mainThread)1512 static ContextImpl createSystemContext(ActivityThread mainThread) { 1513 ContextImpl context = new ContextImpl(); 1514 context.init(Resources.getSystem(), mainThread); 1515 return context; 1516 } 1517 ContextImpl()1518 ContextImpl() { 1519 // For debug only 1520 //++sInstanceCount; 1521 mOuterContext = this; 1522 } 1523 1524 /** 1525 * Create a new ApplicationContext from an existing one. The new one 1526 * works and operates the same as the one it is copying. 1527 * 1528 * @param context Existing application context. 1529 */ ContextImpl(ContextImpl context)1530 public ContextImpl(ContextImpl context) { 1531 ++sInstanceCount; 1532 mPackageInfo = context.mPackageInfo; 1533 mResources = context.mResources; 1534 mMainThread = context.mMainThread; 1535 mContentResolver = context.mContentResolver; 1536 mOuterContext = this; 1537 } 1538 init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread)1539 final void init(LoadedApk packageInfo, 1540 IBinder activityToken, ActivityThread mainThread) { 1541 init(packageInfo, activityToken, mainThread, null); 1542 } 1543 init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread, Resources container)1544 final void init(LoadedApk packageInfo, 1545 IBinder activityToken, ActivityThread mainThread, 1546 Resources container) { 1547 mPackageInfo = packageInfo; 1548 mResources = mPackageInfo.getResources(mainThread); 1549 1550 if (mResources != null && container != null 1551 && container.getCompatibilityInfo().applicationScale != 1552 mResources.getCompatibilityInfo().applicationScale) { 1553 if (DEBUG) { 1554 Log.d(TAG, "loaded context has different scaling. Using container's" + 1555 " compatiblity info:" + container.getDisplayMetrics()); 1556 } 1557 mResources = mainThread.getTopLevelResources( 1558 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy()); 1559 } 1560 mMainThread = mainThread; 1561 mContentResolver = new ApplicationContentResolver(this, mainThread); 1562 1563 setActivityToken(activityToken); 1564 } 1565 init(Resources resources, ActivityThread mainThread)1566 final void init(Resources resources, ActivityThread mainThread) { 1567 mPackageInfo = null; 1568 mResources = resources; 1569 mMainThread = mainThread; 1570 mContentResolver = new ApplicationContentResolver(this, mainThread); 1571 } 1572 scheduleFinalCleanup(String who, String what)1573 final void scheduleFinalCleanup(String who, String what) { 1574 mMainThread.scheduleContextCleanup(this, who, what); 1575 } 1576 performFinalCleanup(String who, String what)1577 final void performFinalCleanup(String who, String what) { 1578 //Log.i(TAG, "Cleanup up context: " + this); 1579 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); 1580 } 1581 getReceiverRestrictedContext()1582 final Context getReceiverRestrictedContext() { 1583 if (mReceiverRestrictedContext != null) { 1584 return mReceiverRestrictedContext; 1585 } 1586 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext()); 1587 } 1588 setActivityToken(IBinder token)1589 final void setActivityToken(IBinder token) { 1590 mActivityToken = token; 1591 } 1592 setOuterContext(Context context)1593 final void setOuterContext(Context context) { 1594 mOuterContext = context; 1595 } 1596 getOuterContext()1597 final Context getOuterContext() { 1598 return mOuterContext; 1599 } 1600 getActivityToken()1601 final IBinder getActivityToken() { 1602 return mActivityToken; 1603 } 1604 setFilePermissionsFromMode(String name, int mode, int extraPermissions)1605 private static void setFilePermissionsFromMode(String name, int mode, 1606 int extraPermissions) { 1607 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR 1608 |FileUtils.S_IRGRP|FileUtils.S_IWGRP 1609 |extraPermissions; 1610 if ((mode&MODE_WORLD_READABLE) != 0) { 1611 perms |= FileUtils.S_IROTH; 1612 } 1613 if ((mode&MODE_WORLD_WRITEABLE) != 0) { 1614 perms |= FileUtils.S_IWOTH; 1615 } 1616 if (DEBUG) { 1617 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode) 1618 + ", perms=0x" + Integer.toHexString(perms)); 1619 } 1620 FileUtils.setPermissions(name, perms, -1, -1); 1621 } 1622 validateFilePath(String name, boolean createDirectory)1623 private File validateFilePath(String name, boolean createDirectory) { 1624 File dir; 1625 File f; 1626 1627 if (name.charAt(0) == File.separatorChar) { 1628 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar)); 1629 dir = new File(dirPath); 1630 name = name.substring(name.lastIndexOf(File.separatorChar)); 1631 f = new File(dir, name); 1632 } else { 1633 dir = getDatabasesDir(); 1634 f = makeFilename(dir, name); 1635 } 1636 1637 if (createDirectory && !dir.isDirectory() && dir.mkdir()) { 1638 FileUtils.setPermissions(dir.getPath(), 1639 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 1640 -1, -1); 1641 } 1642 1643 return f; 1644 } 1645 makeFilename(File base, String name)1646 private File makeFilename(File base, String name) { 1647 if (name.indexOf(File.separatorChar) < 0) { 1648 return new File(base, name); 1649 } 1650 throw new IllegalArgumentException( 1651 "File " + name + " contains a path separator"); 1652 } 1653 1654 // ---------------------------------------------------------------------- 1655 // ---------------------------------------------------------------------- 1656 // ---------------------------------------------------------------------- 1657 1658 private static final class ApplicationContentResolver extends ContentResolver { ApplicationContentResolver(Context context, ActivityThread mainThread)1659 public ApplicationContentResolver(Context context, ActivityThread mainThread) { 1660 super(context); 1661 mMainThread = mainThread; 1662 } 1663 1664 @Override acquireProvider(Context context, String name)1665 protected IContentProvider acquireProvider(Context context, String name) { 1666 return mMainThread.acquireProvider(context, name); 1667 } 1668 1669 @Override acquireExistingProvider(Context context, String name)1670 protected IContentProvider acquireExistingProvider(Context context, String name) { 1671 return mMainThread.acquireExistingProvider(context, name); 1672 } 1673 1674 @Override releaseProvider(IContentProvider provider)1675 public boolean releaseProvider(IContentProvider provider) { 1676 return mMainThread.releaseProvider(provider); 1677 } 1678 1679 private final ActivityThread mMainThread; 1680 } 1681 1682 // ---------------------------------------------------------------------- 1683 // ---------------------------------------------------------------------- 1684 // ---------------------------------------------------------------------- 1685 1686 /*package*/ 1687 static final class ApplicationPackageManager extends PackageManager { 1688 @Override getPackageInfo(String packageName, int flags)1689 public PackageInfo getPackageInfo(String packageName, int flags) 1690 throws NameNotFoundException { 1691 try { 1692 PackageInfo pi = mPM.getPackageInfo(packageName, flags); 1693 if (pi != null) { 1694 return pi; 1695 } 1696 } catch (RemoteException e) { 1697 throw new RuntimeException("Package manager has died", e); 1698 } 1699 1700 throw new NameNotFoundException(packageName); 1701 } 1702 1703 @Override currentToCanonicalPackageNames(String[] names)1704 public String[] currentToCanonicalPackageNames(String[] names) { 1705 try { 1706 return mPM.currentToCanonicalPackageNames(names); 1707 } catch (RemoteException e) { 1708 throw new RuntimeException("Package manager has died", e); 1709 } 1710 } 1711 1712 @Override canonicalToCurrentPackageNames(String[] names)1713 public String[] canonicalToCurrentPackageNames(String[] names) { 1714 try { 1715 return mPM.canonicalToCurrentPackageNames(names); 1716 } catch (RemoteException e) { 1717 throw new RuntimeException("Package manager has died", e); 1718 } 1719 } 1720 1721 @Override getLaunchIntentForPackage(String packageName)1722 public Intent getLaunchIntentForPackage(String packageName) { 1723 // First see if the package has an INFO activity; the existence of 1724 // such an activity is implied to be the desired front-door for the 1725 // overall package (such as if it has multiple launcher entries). 1726 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 1727 intentToResolve.addCategory(Intent.CATEGORY_INFO); 1728 intentToResolve.setPackage(packageName); 1729 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0); 1730 1731 // Otherwise, try to find a main launcher activity. 1732 if (resolveInfo == null) { 1733 // reuse the intent instance 1734 intentToResolve.removeCategory(Intent.CATEGORY_INFO); 1735 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); 1736 intentToResolve.setPackage(packageName); 1737 resolveInfo = resolveActivity(intentToResolve, 0); 1738 } 1739 if (resolveInfo == null) { 1740 return null; 1741 } 1742 Intent intent = new Intent(Intent.ACTION_MAIN); 1743 intent.setClassName(packageName, resolveInfo.activityInfo.name); 1744 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1745 return intent; 1746 } 1747 1748 @Override getPackageGids(String packageName)1749 public int[] getPackageGids(String packageName) 1750 throws NameNotFoundException { 1751 try { 1752 int[] gids = mPM.getPackageGids(packageName); 1753 if (gids == null || gids.length > 0) { 1754 return gids; 1755 } 1756 } catch (RemoteException e) { 1757 throw new RuntimeException("Package manager has died", e); 1758 } 1759 1760 throw new NameNotFoundException(packageName); 1761 } 1762 1763 @Override getPermissionInfo(String name, int flags)1764 public PermissionInfo getPermissionInfo(String name, int flags) 1765 throws NameNotFoundException { 1766 try { 1767 PermissionInfo pi = mPM.getPermissionInfo(name, flags); 1768 if (pi != null) { 1769 return pi; 1770 } 1771 } catch (RemoteException e) { 1772 throw new RuntimeException("Package manager has died", e); 1773 } 1774 1775 throw new NameNotFoundException(name); 1776 } 1777 1778 @Override queryPermissionsByGroup(String group, int flags)1779 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) 1780 throws NameNotFoundException { 1781 try { 1782 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags); 1783 if (pi != null) { 1784 return pi; 1785 } 1786 } catch (RemoteException e) { 1787 throw new RuntimeException("Package manager has died", e); 1788 } 1789 1790 throw new NameNotFoundException(group); 1791 } 1792 1793 @Override getPermissionGroupInfo(String name, int flags)1794 public PermissionGroupInfo getPermissionGroupInfo(String name, 1795 int flags) throws NameNotFoundException { 1796 try { 1797 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags); 1798 if (pgi != null) { 1799 return pgi; 1800 } 1801 } catch (RemoteException e) { 1802 throw new RuntimeException("Package manager has died", e); 1803 } 1804 1805 throw new NameNotFoundException(name); 1806 } 1807 1808 @Override getAllPermissionGroups(int flags)1809 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 1810 try { 1811 return mPM.getAllPermissionGroups(flags); 1812 } catch (RemoteException e) { 1813 throw new RuntimeException("Package manager has died", e); 1814 } 1815 } 1816 1817 @Override getApplicationInfo(String packageName, int flags)1818 public ApplicationInfo getApplicationInfo(String packageName, int flags) 1819 throws NameNotFoundException { 1820 try { 1821 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags); 1822 if (ai != null) { 1823 return ai; 1824 } 1825 } catch (RemoteException e) { 1826 throw new RuntimeException("Package manager has died", e); 1827 } 1828 1829 throw new NameNotFoundException(packageName); 1830 } 1831 1832 @Override getActivityInfo(ComponentName className, int flags)1833 public ActivityInfo getActivityInfo(ComponentName className, int flags) 1834 throws NameNotFoundException { 1835 try { 1836 ActivityInfo ai = mPM.getActivityInfo(className, flags); 1837 if (ai != null) { 1838 return ai; 1839 } 1840 } catch (RemoteException e) { 1841 throw new RuntimeException("Package manager has died", e); 1842 } 1843 1844 throw new NameNotFoundException(className.toString()); 1845 } 1846 1847 @Override getReceiverInfo(ComponentName className, int flags)1848 public ActivityInfo getReceiverInfo(ComponentName className, int flags) 1849 throws NameNotFoundException { 1850 try { 1851 ActivityInfo ai = mPM.getReceiverInfo(className, flags); 1852 if (ai != null) { 1853 return ai; 1854 } 1855 } catch (RemoteException e) { 1856 throw new RuntimeException("Package manager has died", e); 1857 } 1858 1859 throw new NameNotFoundException(className.toString()); 1860 } 1861 1862 @Override getServiceInfo(ComponentName className, int flags)1863 public ServiceInfo getServiceInfo(ComponentName className, int flags) 1864 throws NameNotFoundException { 1865 try { 1866 ServiceInfo si = mPM.getServiceInfo(className, flags); 1867 if (si != null) { 1868 return si; 1869 } 1870 } catch (RemoteException e) { 1871 throw new RuntimeException("Package manager has died", e); 1872 } 1873 1874 throw new NameNotFoundException(className.toString()); 1875 } 1876 1877 @Override getProviderInfo(ComponentName className, int flags)1878 public ProviderInfo getProviderInfo(ComponentName className, int flags) 1879 throws NameNotFoundException { 1880 try { 1881 ProviderInfo pi = mPM.getProviderInfo(className, flags); 1882 if (pi != null) { 1883 return pi; 1884 } 1885 } catch (RemoteException e) { 1886 throw new RuntimeException("Package manager has died", e); 1887 } 1888 1889 throw new NameNotFoundException(className.toString()); 1890 } 1891 1892 @Override getSystemSharedLibraryNames()1893 public String[] getSystemSharedLibraryNames() { 1894 try { 1895 return mPM.getSystemSharedLibraryNames(); 1896 } catch (RemoteException e) { 1897 throw new RuntimeException("Package manager has died", e); 1898 } 1899 } 1900 1901 @Override getSystemAvailableFeatures()1902 public FeatureInfo[] getSystemAvailableFeatures() { 1903 try { 1904 return mPM.getSystemAvailableFeatures(); 1905 } catch (RemoteException e) { 1906 throw new RuntimeException("Package manager has died", e); 1907 } 1908 } 1909 1910 @Override hasSystemFeature(String name)1911 public boolean hasSystemFeature(String name) { 1912 try { 1913 return mPM.hasSystemFeature(name); 1914 } catch (RemoteException e) { 1915 throw new RuntimeException("Package manager has died", e); 1916 } 1917 } 1918 1919 @Override checkPermission(String permName, String pkgName)1920 public int checkPermission(String permName, String pkgName) { 1921 try { 1922 return mPM.checkPermission(permName, pkgName); 1923 } catch (RemoteException e) { 1924 throw new RuntimeException("Package manager has died", e); 1925 } 1926 } 1927 1928 @Override addPermission(PermissionInfo info)1929 public boolean addPermission(PermissionInfo info) { 1930 try { 1931 return mPM.addPermission(info); 1932 } catch (RemoteException e) { 1933 throw new RuntimeException("Package manager has died", e); 1934 } 1935 } 1936 1937 @Override addPermissionAsync(PermissionInfo info)1938 public boolean addPermissionAsync(PermissionInfo info) { 1939 try { 1940 return mPM.addPermissionAsync(info); 1941 } catch (RemoteException e) { 1942 throw new RuntimeException("Package manager has died", e); 1943 } 1944 } 1945 1946 @Override removePermission(String name)1947 public void removePermission(String name) { 1948 try { 1949 mPM.removePermission(name); 1950 } catch (RemoteException e) { 1951 throw new RuntimeException("Package manager has died", e); 1952 } 1953 } 1954 1955 @Override checkSignatures(String pkg1, String pkg2)1956 public int checkSignatures(String pkg1, String pkg2) { 1957 try { 1958 return mPM.checkSignatures(pkg1, pkg2); 1959 } catch (RemoteException e) { 1960 throw new RuntimeException("Package manager has died", e); 1961 } 1962 } 1963 1964 @Override checkSignatures(int uid1, int uid2)1965 public int checkSignatures(int uid1, int uid2) { 1966 try { 1967 return mPM.checkUidSignatures(uid1, uid2); 1968 } catch (RemoteException e) { 1969 throw new RuntimeException("Package manager has died", e); 1970 } 1971 } 1972 1973 @Override getPackagesForUid(int uid)1974 public String[] getPackagesForUid(int uid) { 1975 try { 1976 return mPM.getPackagesForUid(uid); 1977 } catch (RemoteException e) { 1978 throw new RuntimeException("Package manager has died", e); 1979 } 1980 } 1981 1982 @Override getNameForUid(int uid)1983 public String getNameForUid(int uid) { 1984 try { 1985 return mPM.getNameForUid(uid); 1986 } catch (RemoteException e) { 1987 throw new RuntimeException("Package manager has died", e); 1988 } 1989 } 1990 1991 @Override getUidForSharedUser(String sharedUserName)1992 public int getUidForSharedUser(String sharedUserName) 1993 throws NameNotFoundException { 1994 try { 1995 int uid = mPM.getUidForSharedUser(sharedUserName); 1996 if(uid != -1) { 1997 return uid; 1998 } 1999 } catch (RemoteException e) { 2000 throw new RuntimeException("Package manager has died", e); 2001 } 2002 throw new NameNotFoundException("No shared userid for user:"+sharedUserName); 2003 } 2004 2005 @SuppressWarnings("unchecked") 2006 @Override getInstalledPackages(int flags)2007 public List<PackageInfo> getInstalledPackages(int flags) { 2008 try { 2009 final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); 2010 PackageInfo lastItem = null; 2011 ParceledListSlice<PackageInfo> slice; 2012 2013 do { 2014 final String lastKey = lastItem != null ? lastItem.packageName : null; 2015 slice = mPM.getInstalledPackages(flags, lastKey); 2016 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); 2017 } while (!slice.isLastSlice()); 2018 2019 return packageInfos; 2020 } catch (RemoteException e) { 2021 throw new RuntimeException("Package manager has died", e); 2022 } 2023 } 2024 2025 @SuppressWarnings("unchecked") 2026 @Override getInstalledApplications(int flags)2027 public List<ApplicationInfo> getInstalledApplications(int flags) { 2028 try { 2029 final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>(); 2030 ApplicationInfo lastItem = null; 2031 ParceledListSlice<ApplicationInfo> slice; 2032 2033 do { 2034 final String lastKey = lastItem != null ? lastItem.packageName : null; 2035 slice = mPM.getInstalledApplications(flags, lastKey); 2036 lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR); 2037 } while (!slice.isLastSlice()); 2038 2039 return applicationInfos; 2040 } catch (RemoteException e) { 2041 throw new RuntimeException("Package manager has died", e); 2042 } 2043 } 2044 2045 @Override resolveActivity(Intent intent, int flags)2046 public ResolveInfo resolveActivity(Intent intent, int flags) { 2047 try { 2048 return mPM.resolveIntent( 2049 intent, 2050 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2051 flags); 2052 } catch (RemoteException e) { 2053 throw new RuntimeException("Package manager has died", e); 2054 } 2055 } 2056 2057 @Override queryIntentActivities(Intent intent, int flags)2058 public List<ResolveInfo> queryIntentActivities(Intent intent, 2059 int flags) { 2060 try { 2061 return mPM.queryIntentActivities( 2062 intent, 2063 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2064 flags); 2065 } catch (RemoteException e) { 2066 throw new RuntimeException("Package manager has died", e); 2067 } 2068 } 2069 2070 @Override queryIntentActivityOptions( ComponentName caller, Intent[] specifics, Intent intent, int flags)2071 public List<ResolveInfo> queryIntentActivityOptions( 2072 ComponentName caller, Intent[] specifics, Intent intent, 2073 int flags) { 2074 final ContentResolver resolver = mContext.getContentResolver(); 2075 2076 String[] specificTypes = null; 2077 if (specifics != null) { 2078 final int N = specifics.length; 2079 for (int i=0; i<N; i++) { 2080 Intent sp = specifics[i]; 2081 if (sp != null) { 2082 String t = sp.resolveTypeIfNeeded(resolver); 2083 if (t != null) { 2084 if (specificTypes == null) { 2085 specificTypes = new String[N]; 2086 } 2087 specificTypes[i] = t; 2088 } 2089 } 2090 } 2091 } 2092 2093 try { 2094 return mPM.queryIntentActivityOptions(caller, specifics, 2095 specificTypes, intent, intent.resolveTypeIfNeeded(resolver), 2096 flags); 2097 } catch (RemoteException e) { 2098 throw new RuntimeException("Package manager has died", e); 2099 } 2100 } 2101 2102 @Override queryBroadcastReceivers(Intent intent, int flags)2103 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) { 2104 try { 2105 return mPM.queryIntentReceivers( 2106 intent, 2107 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2108 flags); 2109 } catch (RemoteException e) { 2110 throw new RuntimeException("Package manager has died", e); 2111 } 2112 } 2113 2114 @Override resolveService(Intent intent, int flags)2115 public ResolveInfo resolveService(Intent intent, int flags) { 2116 try { 2117 return mPM.resolveService( 2118 intent, 2119 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2120 flags); 2121 } catch (RemoteException e) { 2122 throw new RuntimeException("Package manager has died", e); 2123 } 2124 } 2125 2126 @Override queryIntentServices(Intent intent, int flags)2127 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) { 2128 try { 2129 return mPM.queryIntentServices( 2130 intent, 2131 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2132 flags); 2133 } catch (RemoteException e) { 2134 throw new RuntimeException("Package manager has died", e); 2135 } 2136 } 2137 2138 @Override resolveContentProvider(String name, int flags)2139 public ProviderInfo resolveContentProvider(String name, 2140 int flags) { 2141 try { 2142 return mPM.resolveContentProvider(name, flags); 2143 } catch (RemoteException e) { 2144 throw new RuntimeException("Package manager has died", e); 2145 } 2146 } 2147 2148 @Override queryContentProviders(String processName, int uid, int flags)2149 public List<ProviderInfo> queryContentProviders(String processName, 2150 int uid, int flags) { 2151 try { 2152 return mPM.queryContentProviders(processName, uid, flags); 2153 } catch (RemoteException e) { 2154 throw new RuntimeException("Package manager has died", e); 2155 } 2156 } 2157 2158 @Override getInstrumentationInfo( ComponentName className, int flags)2159 public InstrumentationInfo getInstrumentationInfo( 2160 ComponentName className, int flags) 2161 throws NameNotFoundException { 2162 try { 2163 InstrumentationInfo ii = mPM.getInstrumentationInfo( 2164 className, flags); 2165 if (ii != null) { 2166 return ii; 2167 } 2168 } catch (RemoteException e) { 2169 throw new RuntimeException("Package manager has died", e); 2170 } 2171 2172 throw new NameNotFoundException(className.toString()); 2173 } 2174 2175 @Override queryInstrumentation( String targetPackage, int flags)2176 public List<InstrumentationInfo> queryInstrumentation( 2177 String targetPackage, int flags) { 2178 try { 2179 return mPM.queryInstrumentation(targetPackage, flags); 2180 } catch (RemoteException e) { 2181 throw new RuntimeException("Package manager has died", e); 2182 } 2183 } 2184 getDrawable(String packageName, int resid, ApplicationInfo appInfo)2185 @Override public Drawable getDrawable(String packageName, int resid, 2186 ApplicationInfo appInfo) { 2187 ResourceName name = new ResourceName(packageName, resid); 2188 Drawable dr = getCachedIcon(name); 2189 if (dr != null) { 2190 return dr; 2191 } 2192 if (appInfo == null) { 2193 try { 2194 appInfo = getApplicationInfo(packageName, 0); 2195 } catch (NameNotFoundException e) { 2196 return null; 2197 } 2198 } 2199 try { 2200 Resources r = getResourcesForApplication(appInfo); 2201 dr = r.getDrawable(resid); 2202 if (false) { 2203 RuntimeException e = new RuntimeException("here"); 2204 e.fillInStackTrace(); 2205 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid) 2206 + " from package " + packageName 2207 + ": app scale=" + r.getCompatibilityInfo().applicationScale 2208 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale, 2209 e); 2210 } 2211 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x" 2212 + Integer.toHexString(resid) + " from " + r 2213 + ": " + dr); 2214 putCachedIcon(name, dr); 2215 return dr; 2216 } catch (NameNotFoundException e) { 2217 Log.w("PackageManager", "Failure retrieving resources for" 2218 + appInfo.packageName); 2219 } catch (RuntimeException e) { 2220 // If an exception was thrown, fall through to return 2221 // default icon. 2222 Log.w("PackageManager", "Failure retrieving icon 0x" 2223 + Integer.toHexString(resid) + " in package " 2224 + packageName, e); 2225 } 2226 return null; 2227 } 2228 getActivityIcon(ComponentName activityName)2229 @Override public Drawable getActivityIcon(ComponentName activityName) 2230 throws NameNotFoundException { 2231 return getActivityInfo(activityName, 0).loadIcon(this); 2232 } 2233 getActivityIcon(Intent intent)2234 @Override public Drawable getActivityIcon(Intent intent) 2235 throws NameNotFoundException { 2236 if (intent.getComponent() != null) { 2237 return getActivityIcon(intent.getComponent()); 2238 } 2239 2240 ResolveInfo info = resolveActivity( 2241 intent, PackageManager.MATCH_DEFAULT_ONLY); 2242 if (info != null) { 2243 return info.activityInfo.loadIcon(this); 2244 } 2245 2246 throw new NameNotFoundException(intent.toURI()); 2247 } 2248 getDefaultActivityIcon()2249 @Override public Drawable getDefaultActivityIcon() { 2250 return Resources.getSystem().getDrawable( 2251 com.android.internal.R.drawable.sym_def_app_icon); 2252 } 2253 getApplicationIcon(ApplicationInfo info)2254 @Override public Drawable getApplicationIcon(ApplicationInfo info) { 2255 return info.loadIcon(this); 2256 } 2257 getApplicationIcon(String packageName)2258 @Override public Drawable getApplicationIcon(String packageName) 2259 throws NameNotFoundException { 2260 return getApplicationIcon(getApplicationInfo(packageName, 0)); 2261 } 2262 2263 @Override getActivityLogo(ComponentName activityName)2264 public Drawable getActivityLogo(ComponentName activityName) 2265 throws NameNotFoundException { 2266 return getActivityInfo(activityName, 0).loadLogo(this); 2267 } 2268 2269 @Override getActivityLogo(Intent intent)2270 public Drawable getActivityLogo(Intent intent) 2271 throws NameNotFoundException { 2272 if (intent.getComponent() != null) { 2273 return getActivityLogo(intent.getComponent()); 2274 } 2275 2276 ResolveInfo info = resolveActivity( 2277 intent, PackageManager.MATCH_DEFAULT_ONLY); 2278 if (info != null) { 2279 return info.activityInfo.loadLogo(this); 2280 } 2281 2282 throw new NameNotFoundException(intent.toUri(0)); 2283 } 2284 2285 @Override getApplicationLogo(ApplicationInfo info)2286 public Drawable getApplicationLogo(ApplicationInfo info) { 2287 return info.loadLogo(this); 2288 } 2289 2290 @Override getApplicationLogo(String packageName)2291 public Drawable getApplicationLogo(String packageName) 2292 throws NameNotFoundException { 2293 return getApplicationLogo(getApplicationInfo(packageName, 0)); 2294 } 2295 getResourcesForActivity( ComponentName activityName)2296 @Override public Resources getResourcesForActivity( 2297 ComponentName activityName) throws NameNotFoundException { 2298 return getResourcesForApplication( 2299 getActivityInfo(activityName, 0).applicationInfo); 2300 } 2301 getResourcesForApplication( ApplicationInfo app)2302 @Override public Resources getResourcesForApplication( 2303 ApplicationInfo app) throws NameNotFoundException { 2304 if (app.packageName.equals("system")) { 2305 return mContext.mMainThread.getSystemContext().getResources(); 2306 } 2307 Resources r = mContext.mMainThread.getTopLevelResources( 2308 app.uid == Process.myUid() ? app.sourceDir 2309 : app.publicSourceDir, mContext.mPackageInfo); 2310 if (r != null) { 2311 return r; 2312 } 2313 throw new NameNotFoundException("Unable to open " + app.publicSourceDir); 2314 } 2315 getResourcesForApplication( String appPackageName)2316 @Override public Resources getResourcesForApplication( 2317 String appPackageName) throws NameNotFoundException { 2318 return getResourcesForApplication( 2319 getApplicationInfo(appPackageName, 0)); 2320 } 2321 2322 int mCachedSafeMode = -1; isSafeMode()2323 @Override public boolean isSafeMode() { 2324 try { 2325 if (mCachedSafeMode < 0) { 2326 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0; 2327 } 2328 return mCachedSafeMode != 0; 2329 } catch (RemoteException e) { 2330 throw new RuntimeException("Package manager has died", e); 2331 } 2332 } 2333 configurationChanged()2334 static void configurationChanged() { 2335 synchronized (sSync) { 2336 sIconCache.clear(); 2337 sStringCache.clear(); 2338 } 2339 } 2340 ApplicationPackageManager(ContextImpl context, IPackageManager pm)2341 ApplicationPackageManager(ContextImpl context, 2342 IPackageManager pm) { 2343 mContext = context; 2344 mPM = pm; 2345 } 2346 getCachedIcon(ResourceName name)2347 private Drawable getCachedIcon(ResourceName name) { 2348 synchronized (sSync) { 2349 WeakReference<Drawable> wr = sIconCache.get(name); 2350 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for " 2351 + name + ": " + wr); 2352 if (wr != null) { // we have the activity 2353 Drawable dr = wr.get(); 2354 if (dr != null) { 2355 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for " 2356 + name + ": " + dr); 2357 return dr; 2358 } 2359 // our entry has been purged 2360 sIconCache.remove(name); 2361 } 2362 } 2363 return null; 2364 } 2365 putCachedIcon(ResourceName name, Drawable dr)2366 private void putCachedIcon(ResourceName name, Drawable dr) { 2367 synchronized (sSync) { 2368 sIconCache.put(name, new WeakReference<Drawable>(dr)); 2369 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for " 2370 + name + ": " + dr); 2371 } 2372 } 2373 handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo)2374 static final void handlePackageBroadcast(int cmd, String[] pkgList, 2375 boolean hasPkgInfo) { 2376 boolean immediateGc = false; 2377 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) { 2378 immediateGc = true; 2379 } 2380 if (pkgList != null && (pkgList.length > 0)) { 2381 boolean needCleanup = false; 2382 for (String ssp : pkgList) { 2383 synchronized (sSync) { 2384 if (sIconCache.size() > 0) { 2385 Iterator<ResourceName> it = sIconCache.keySet().iterator(); 2386 while (it.hasNext()) { 2387 ResourceName nm = it.next(); 2388 if (nm.packageName.equals(ssp)) { 2389 //Log.i(TAG, "Removing cached drawable for " + nm); 2390 it.remove(); 2391 needCleanup = true; 2392 } 2393 } 2394 } 2395 if (sStringCache.size() > 0) { 2396 Iterator<ResourceName> it = sStringCache.keySet().iterator(); 2397 while (it.hasNext()) { 2398 ResourceName nm = it.next(); 2399 if (nm.packageName.equals(ssp)) { 2400 //Log.i(TAG, "Removing cached string for " + nm); 2401 it.remove(); 2402 needCleanup = true; 2403 } 2404 } 2405 } 2406 } 2407 } 2408 if (needCleanup || hasPkgInfo) { 2409 if (immediateGc) { 2410 // Schedule an immediate gc. 2411 Runtime.getRuntime().gc(); 2412 } else { 2413 ActivityThread.currentActivityThread().scheduleGcIdler(); 2414 } 2415 } 2416 } 2417 } 2418 2419 private static final class ResourceName { 2420 final String packageName; 2421 final int iconId; 2422 ResourceName(String _packageName, int _iconId)2423 ResourceName(String _packageName, int _iconId) { 2424 packageName = _packageName; 2425 iconId = _iconId; 2426 } 2427 ResourceName(ApplicationInfo aInfo, int _iconId)2428 ResourceName(ApplicationInfo aInfo, int _iconId) { 2429 this(aInfo.packageName, _iconId); 2430 } 2431 ResourceName(ComponentInfo cInfo, int _iconId)2432 ResourceName(ComponentInfo cInfo, int _iconId) { 2433 this(cInfo.applicationInfo.packageName, _iconId); 2434 } 2435 ResourceName(ResolveInfo rInfo, int _iconId)2436 ResourceName(ResolveInfo rInfo, int _iconId) { 2437 this(rInfo.activityInfo.applicationInfo.packageName, _iconId); 2438 } 2439 2440 @Override equals(Object o)2441 public boolean equals(Object o) { 2442 if (this == o) return true; 2443 if (o == null || getClass() != o.getClass()) return false; 2444 2445 ResourceName that = (ResourceName) o; 2446 2447 if (iconId != that.iconId) return false; 2448 return !(packageName != null ? 2449 !packageName.equals(that.packageName) : that.packageName != null); 2450 2451 } 2452 2453 @Override hashCode()2454 public int hashCode() { 2455 int result; 2456 result = packageName.hashCode(); 2457 result = 31 * result + iconId; 2458 return result; 2459 } 2460 2461 @Override toString()2462 public String toString() { 2463 return "{ResourceName " + packageName + " / " + iconId + "}"; 2464 } 2465 } 2466 getCachedString(ResourceName name)2467 private CharSequence getCachedString(ResourceName name) { 2468 synchronized (sSync) { 2469 WeakReference<CharSequence> wr = sStringCache.get(name); 2470 if (wr != null) { // we have the activity 2471 CharSequence cs = wr.get(); 2472 if (cs != null) { 2473 return cs; 2474 } 2475 // our entry has been purged 2476 sStringCache.remove(name); 2477 } 2478 } 2479 return null; 2480 } 2481 putCachedString(ResourceName name, CharSequence cs)2482 private void putCachedString(ResourceName name, CharSequence cs) { 2483 synchronized (sSync) { 2484 sStringCache.put(name, new WeakReference<CharSequence>(cs)); 2485 } 2486 } 2487 2488 @Override getText(String packageName, int resid, ApplicationInfo appInfo)2489 public CharSequence getText(String packageName, int resid, 2490 ApplicationInfo appInfo) { 2491 ResourceName name = new ResourceName(packageName, resid); 2492 CharSequence text = getCachedString(name); 2493 if (text != null) { 2494 return text; 2495 } 2496 if (appInfo == null) { 2497 try { 2498 appInfo = getApplicationInfo(packageName, 0); 2499 } catch (NameNotFoundException e) { 2500 return null; 2501 } 2502 } 2503 try { 2504 Resources r = getResourcesForApplication(appInfo); 2505 text = r.getText(resid); 2506 putCachedString(name, text); 2507 return text; 2508 } catch (NameNotFoundException e) { 2509 Log.w("PackageManager", "Failure retrieving resources for" 2510 + appInfo.packageName); 2511 } catch (RuntimeException e) { 2512 // If an exception was thrown, fall through to return 2513 // default icon. 2514 Log.w("PackageManager", "Failure retrieving text 0x" 2515 + Integer.toHexString(resid) + " in package " 2516 + packageName, e); 2517 } 2518 return null; 2519 } 2520 2521 @Override getXml(String packageName, int resid, ApplicationInfo appInfo)2522 public XmlResourceParser getXml(String packageName, int resid, 2523 ApplicationInfo appInfo) { 2524 if (appInfo == null) { 2525 try { 2526 appInfo = getApplicationInfo(packageName, 0); 2527 } catch (NameNotFoundException e) { 2528 return null; 2529 } 2530 } 2531 try { 2532 Resources r = getResourcesForApplication(appInfo); 2533 return r.getXml(resid); 2534 } catch (RuntimeException e) { 2535 // If an exception was thrown, fall through to return 2536 // default icon. 2537 Log.w("PackageManager", "Failure retrieving xml 0x" 2538 + Integer.toHexString(resid) + " in package " 2539 + packageName, e); 2540 } catch (NameNotFoundException e) { 2541 Log.w("PackageManager", "Failure retrieving resources for" 2542 + appInfo.packageName); 2543 } 2544 return null; 2545 } 2546 2547 @Override getApplicationLabel(ApplicationInfo info)2548 public CharSequence getApplicationLabel(ApplicationInfo info) { 2549 return info.loadLabel(this); 2550 } 2551 2552 @Override installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName)2553 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, 2554 String installerPackageName) { 2555 try { 2556 mPM.installPackage(packageURI, observer, flags, installerPackageName); 2557 } catch (RemoteException e) { 2558 // Should never happen! 2559 } 2560 } 2561 2562 @Override movePackage(String packageName, IPackageMoveObserver observer, int flags)2563 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { 2564 try { 2565 mPM.movePackage(packageName, observer, flags); 2566 } catch (RemoteException e) { 2567 // Should never happen! 2568 } 2569 } 2570 2571 @Override getInstallerPackageName(String packageName)2572 public String getInstallerPackageName(String packageName) { 2573 try { 2574 return mPM.getInstallerPackageName(packageName); 2575 } catch (RemoteException e) { 2576 // Should never happen! 2577 } 2578 return null; 2579 } 2580 2581 @Override deletePackage(String packageName, IPackageDeleteObserver observer, int flags)2582 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 2583 try { 2584 mPM.deletePackage(packageName, observer, flags); 2585 } catch (RemoteException e) { 2586 // Should never happen! 2587 } 2588 } 2589 @Override clearApplicationUserData(String packageName, IPackageDataObserver observer)2590 public void clearApplicationUserData(String packageName, 2591 IPackageDataObserver observer) { 2592 try { 2593 mPM.clearApplicationUserData(packageName, observer); 2594 } catch (RemoteException e) { 2595 // Should never happen! 2596 } 2597 } 2598 @Override deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer)2599 public void deleteApplicationCacheFiles(String packageName, 2600 IPackageDataObserver observer) { 2601 try { 2602 mPM.deleteApplicationCacheFiles(packageName, observer); 2603 } catch (RemoteException e) { 2604 // Should never happen! 2605 } 2606 } 2607 @Override freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer)2608 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) { 2609 try { 2610 mPM.freeStorageAndNotify(idealStorageSize, observer); 2611 } catch (RemoteException e) { 2612 // Should never happen! 2613 } 2614 } 2615 2616 @Override freeStorage(long freeStorageSize, IntentSender pi)2617 public void freeStorage(long freeStorageSize, IntentSender pi) { 2618 try { 2619 mPM.freeStorage(freeStorageSize, pi); 2620 } catch (RemoteException e) { 2621 // Should never happen! 2622 } 2623 } 2624 2625 @Override getPackageSizeInfo(String packageName, IPackageStatsObserver observer)2626 public void getPackageSizeInfo(String packageName, 2627 IPackageStatsObserver observer) { 2628 try { 2629 mPM.getPackageSizeInfo(packageName, observer); 2630 } catch (RemoteException e) { 2631 // Should never happen! 2632 } 2633 } 2634 @Override addPackageToPreferred(String packageName)2635 public void addPackageToPreferred(String packageName) { 2636 try { 2637 mPM.addPackageToPreferred(packageName); 2638 } catch (RemoteException e) { 2639 // Should never happen! 2640 } 2641 } 2642 2643 @Override removePackageFromPreferred(String packageName)2644 public void removePackageFromPreferred(String packageName) { 2645 try { 2646 mPM.removePackageFromPreferred(packageName); 2647 } catch (RemoteException e) { 2648 // Should never happen! 2649 } 2650 } 2651 2652 @Override getPreferredPackages(int flags)2653 public List<PackageInfo> getPreferredPackages(int flags) { 2654 try { 2655 return mPM.getPreferredPackages(flags); 2656 } catch (RemoteException e) { 2657 // Should never happen! 2658 } 2659 return new ArrayList<PackageInfo>(); 2660 } 2661 2662 @Override addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)2663 public void addPreferredActivity(IntentFilter filter, 2664 int match, ComponentName[] set, ComponentName activity) { 2665 try { 2666 mPM.addPreferredActivity(filter, match, set, activity); 2667 } catch (RemoteException e) { 2668 // Should never happen! 2669 } 2670 } 2671 2672 @Override replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)2673 public void replacePreferredActivity(IntentFilter filter, 2674 int match, ComponentName[] set, ComponentName activity) { 2675 try { 2676 mPM.replacePreferredActivity(filter, match, set, activity); 2677 } catch (RemoteException e) { 2678 // Should never happen! 2679 } 2680 } 2681 2682 @Override clearPackagePreferredActivities(String packageName)2683 public void clearPackagePreferredActivities(String packageName) { 2684 try { 2685 mPM.clearPackagePreferredActivities(packageName); 2686 } catch (RemoteException e) { 2687 // Should never happen! 2688 } 2689 } 2690 2691 @Override getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)2692 public int getPreferredActivities(List<IntentFilter> outFilters, 2693 List<ComponentName> outActivities, String packageName) { 2694 try { 2695 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 2696 } catch (RemoteException e) { 2697 // Should never happen! 2698 } 2699 return 0; 2700 } 2701 2702 @Override setComponentEnabledSetting(ComponentName componentName, int newState, int flags)2703 public void setComponentEnabledSetting(ComponentName componentName, 2704 int newState, int flags) { 2705 try { 2706 mPM.setComponentEnabledSetting(componentName, newState, flags); 2707 } catch (RemoteException e) { 2708 // Should never happen! 2709 } 2710 } 2711 2712 @Override getComponentEnabledSetting(ComponentName componentName)2713 public int getComponentEnabledSetting(ComponentName componentName) { 2714 try { 2715 return mPM.getComponentEnabledSetting(componentName); 2716 } catch (RemoteException e) { 2717 // Should never happen! 2718 } 2719 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2720 } 2721 2722 @Override setApplicationEnabledSetting(String packageName, int newState, int flags)2723 public void setApplicationEnabledSetting(String packageName, 2724 int newState, int flags) { 2725 try { 2726 mPM.setApplicationEnabledSetting(packageName, newState, flags); 2727 } catch (RemoteException e) { 2728 // Should never happen! 2729 } 2730 } 2731 2732 @Override getApplicationEnabledSetting(String packageName)2733 public int getApplicationEnabledSetting(String packageName) { 2734 try { 2735 return mPM.getApplicationEnabledSetting(packageName); 2736 } catch (RemoteException e) { 2737 // Should never happen! 2738 } 2739 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2740 } 2741 2742 private final ContextImpl mContext; 2743 private final IPackageManager mPM; 2744 2745 private static final Object sSync = new Object(); 2746 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache 2747 = new HashMap<ResourceName, WeakReference<Drawable> >(); 2748 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache 2749 = new HashMap<ResourceName, WeakReference<CharSequence> >(); 2750 } 2751 2752 // ---------------------------------------------------------------------- 2753 // ---------------------------------------------------------------------- 2754 // ---------------------------------------------------------------------- 2755 2756 private static final class SharedPreferencesImpl implements SharedPreferences { 2757 2758 // Lock ordering rules: 2759 // - acquire SharedPreferencesImpl.this before EditorImpl.this 2760 // - acquire mWritingToDiskLock before EditorImpl.this 2761 2762 private final File mFile; 2763 private final File mBackupFile; 2764 private final int mMode; 2765 2766 private Map<String, Object> mMap; // guarded by 'this' 2767 private int mDiskWritesInFlight = 0; // guarded by 'this' 2768 private boolean mLoaded = false; // guarded by 'this' 2769 private long mStatTimestamp; // guarded by 'this' 2770 private long mStatSize; // guarded by 'this' 2771 2772 private final Object mWritingToDiskLock = new Object(); 2773 private static final Object mContent = new Object(); 2774 private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners; 2775 SharedPreferencesImpl( File file, int mode, Map initialContents)2776 SharedPreferencesImpl( 2777 File file, int mode, Map initialContents) { 2778 mFile = file; 2779 mBackupFile = makeBackupFile(file); 2780 mMode = mode; 2781 mLoaded = initialContents != null; 2782 mMap = initialContents != null ? initialContents : new HashMap<String, Object>(); 2783 FileStatus stat = new FileStatus(); 2784 if (FileUtils.getFileStatus(file.getPath(), stat)) { 2785 mStatTimestamp = stat.mtime; 2786 } 2787 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>(); 2788 } 2789 2790 // Has this SharedPreferences ever had values assigned to it? isLoaded()2791 boolean isLoaded() { 2792 synchronized (this) { 2793 return mLoaded; 2794 } 2795 } 2796 2797 // Has the file changed out from under us? i.e. writes that 2798 // we didn't instigate. hasFileChangedUnexpectedly()2799 public boolean hasFileChangedUnexpectedly() { 2800 synchronized (this) { 2801 if (mDiskWritesInFlight > 0) { 2802 // If we know we caused it, it's not unexpected. 2803 if (DEBUG) Log.d(TAG, "disk write in flight, not unexpected."); 2804 return false; 2805 } 2806 } 2807 FileStatus stat = new FileStatus(); 2808 if (!FileUtils.getFileStatus(mFile.getPath(), stat)) { 2809 return true; 2810 } 2811 synchronized (this) { 2812 return mStatTimestamp != stat.mtime || mStatSize != stat.size; 2813 } 2814 } 2815 replace(Map newContents, FileStatus stat)2816 /* package */ void replace(Map newContents, FileStatus stat) { 2817 synchronized (this) { 2818 mLoaded = true; 2819 if (newContents != null) { 2820 mMap = newContents; 2821 } 2822 if (stat != null) { 2823 mStatTimestamp = stat.mtime; 2824 mStatSize = stat.size; 2825 } 2826 } 2827 } 2828 registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener)2829 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { 2830 synchronized(this) { 2831 mListeners.put(listener, mContent); 2832 } 2833 } 2834 unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener)2835 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { 2836 synchronized(this) { 2837 mListeners.remove(listener); 2838 } 2839 } 2840 getAll()2841 public Map<String, ?> getAll() { 2842 synchronized(this) { 2843 //noinspection unchecked 2844 return new HashMap<String, Object>(mMap); 2845 } 2846 } 2847 getString(String key, String defValue)2848 public String getString(String key, String defValue) { 2849 synchronized (this) { 2850 String v = (String)mMap.get(key); 2851 return v != null ? v : defValue; 2852 } 2853 } 2854 getInt(String key, int defValue)2855 public int getInt(String key, int defValue) { 2856 synchronized (this) { 2857 Integer v = (Integer)mMap.get(key); 2858 return v != null ? v : defValue; 2859 } 2860 } getLong(String key, long defValue)2861 public long getLong(String key, long defValue) { 2862 synchronized (this) { 2863 Long v = (Long)mMap.get(key); 2864 return v != null ? v : defValue; 2865 } 2866 } getFloat(String key, float defValue)2867 public float getFloat(String key, float defValue) { 2868 synchronized (this) { 2869 Float v = (Float)mMap.get(key); 2870 return v != null ? v : defValue; 2871 } 2872 } getBoolean(String key, boolean defValue)2873 public boolean getBoolean(String key, boolean defValue) { 2874 synchronized (this) { 2875 Boolean v = (Boolean)mMap.get(key); 2876 return v != null ? v : defValue; 2877 } 2878 } 2879 contains(String key)2880 public boolean contains(String key) { 2881 synchronized (this) { 2882 return mMap.containsKey(key); 2883 } 2884 } 2885 edit()2886 public Editor edit() { 2887 return new EditorImpl(); 2888 } 2889 2890 // Return value from EditorImpl#commitToMemory() 2891 private static class MemoryCommitResult { 2892 public boolean changesMade; // any keys different? 2893 public List<String> keysModified; // may be null 2894 public Set<OnSharedPreferenceChangeListener> listeners; // may be null 2895 public Map<?, ?> mapToWriteToDisk; 2896 public final CountDownLatch writtenToDiskLatch = new CountDownLatch(1); 2897 public volatile boolean writeToDiskResult = false; 2898 setDiskWriteResult(boolean result)2899 public void setDiskWriteResult(boolean result) { 2900 writeToDiskResult = result; 2901 writtenToDiskLatch.countDown(); 2902 } 2903 } 2904 2905 public final class EditorImpl implements Editor { 2906 private final Map<String, Object> mModified = Maps.newHashMap(); 2907 private boolean mClear = false; 2908 putString(String key, String value)2909 public Editor putString(String key, String value) { 2910 synchronized (this) { 2911 mModified.put(key, value); 2912 return this; 2913 } 2914 } putInt(String key, int value)2915 public Editor putInt(String key, int value) { 2916 synchronized (this) { 2917 mModified.put(key, value); 2918 return this; 2919 } 2920 } putLong(String key, long value)2921 public Editor putLong(String key, long value) { 2922 synchronized (this) { 2923 mModified.put(key, value); 2924 return this; 2925 } 2926 } putFloat(String key, float value)2927 public Editor putFloat(String key, float value) { 2928 synchronized (this) { 2929 mModified.put(key, value); 2930 return this; 2931 } 2932 } putBoolean(String key, boolean value)2933 public Editor putBoolean(String key, boolean value) { 2934 synchronized (this) { 2935 mModified.put(key, value); 2936 return this; 2937 } 2938 } 2939 remove(String key)2940 public Editor remove(String key) { 2941 synchronized (this) { 2942 mModified.put(key, this); 2943 return this; 2944 } 2945 } 2946 clear()2947 public Editor clear() { 2948 synchronized (this) { 2949 mClear = true; 2950 return this; 2951 } 2952 } 2953 apply()2954 public void apply() { 2955 final MemoryCommitResult mcr = commitToMemory(); 2956 final Runnable awaitCommit = new Runnable() { 2957 public void run() { 2958 try { 2959 mcr.writtenToDiskLatch.await(); 2960 } catch (InterruptedException ignored) { 2961 } 2962 } 2963 }; 2964 2965 QueuedWork.add(awaitCommit); 2966 2967 Runnable postWriteRunnable = new Runnable() { 2968 public void run() { 2969 awaitCommit.run(); 2970 QueuedWork.remove(awaitCommit); 2971 } 2972 }; 2973 2974 SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable); 2975 2976 // Okay to notify the listeners before it's hit disk 2977 // because the listeners should always get the same 2978 // SharedPreferences instance back, which has the 2979 // changes reflected in memory. 2980 notifyListeners(mcr); 2981 } 2982 2983 // Returns true if any changes were made commitToMemory()2984 private MemoryCommitResult commitToMemory() { 2985 MemoryCommitResult mcr = new MemoryCommitResult(); 2986 synchronized (SharedPreferencesImpl.this) { 2987 // We optimistically don't make a deep copy until 2988 // a memory commit comes in when we're already 2989 // writing to disk. 2990 if (mDiskWritesInFlight > 0) { 2991 // We can't modify our mMap as a currently 2992 // in-flight write owns it. Clone it before 2993 // modifying it. 2994 // noinspection unchecked 2995 mMap = new HashMap<String, Object>(mMap); 2996 } 2997 mcr.mapToWriteToDisk = mMap; 2998 mDiskWritesInFlight++; 2999 3000 boolean hasListeners = mListeners.size() > 0; 3001 if (hasListeners) { 3002 mcr.keysModified = new ArrayList<String>(); 3003 mcr.listeners = 3004 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet()); 3005 } 3006 3007 synchronized (this) { 3008 if (mClear) { 3009 if (!mMap.isEmpty()) { 3010 mcr.changesMade = true; 3011 mMap.clear(); 3012 } 3013 mClear = false; 3014 } 3015 3016 for (Entry<String, Object> e : mModified.entrySet()) { 3017 String k = e.getKey(); 3018 Object v = e.getValue(); 3019 if (v == this) { // magic value for a removal mutation 3020 if (!mMap.containsKey(k)) { 3021 continue; 3022 } 3023 mMap.remove(k); 3024 } else { 3025 boolean isSame = false; 3026 if (mMap.containsKey(k)) { 3027 Object existingValue = mMap.get(k); 3028 if (existingValue != null && existingValue.equals(v)) { 3029 continue; 3030 } 3031 } 3032 mMap.put(k, v); 3033 } 3034 3035 mcr.changesMade = true; 3036 if (hasListeners) { 3037 mcr.keysModified.add(k); 3038 } 3039 } 3040 3041 mModified.clear(); 3042 } 3043 } 3044 return mcr; 3045 } 3046 commit()3047 public boolean commit() { 3048 MemoryCommitResult mcr = commitToMemory(); 3049 SharedPreferencesImpl.this.enqueueDiskWrite( 3050 mcr, null /* sync write on this thread okay */); 3051 try { 3052 mcr.writtenToDiskLatch.await(); 3053 } catch (InterruptedException e) { 3054 return false; 3055 } 3056 notifyListeners(mcr); 3057 return mcr.writeToDiskResult; 3058 } 3059 notifyListeners(final MemoryCommitResult mcr)3060 private void notifyListeners(final MemoryCommitResult mcr) { 3061 if (mcr.listeners == null || mcr.keysModified == null || 3062 mcr.keysModified.size() == 0) { 3063 return; 3064 } 3065 if (Looper.myLooper() == Looper.getMainLooper()) { 3066 for (int i = mcr.keysModified.size() - 1; i >= 0; i--) { 3067 final String key = mcr.keysModified.get(i); 3068 for (OnSharedPreferenceChangeListener listener : mcr.listeners) { 3069 if (listener != null) { 3070 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key); 3071 } 3072 } 3073 } 3074 } else { 3075 // Run this function on the main thread. 3076 ActivityThread.sMainThreadHandler.post(new Runnable() { 3077 public void run() { 3078 notifyListeners(mcr); 3079 } 3080 }); 3081 } 3082 } 3083 } 3084 3085 /** 3086 * Enqueue an already-committed-to-memory result to be written 3087 * to disk. 3088 * 3089 * They will be written to disk one-at-a-time in the order 3090 * that they're enqueued. 3091 * 3092 * @param postWriteRunnable if non-null, we're being called 3093 * from apply() and this is the runnable to run after 3094 * the write proceeds. if null (from a regular commit()), 3095 * then we're allowed to do this disk write on the main 3096 * thread (which in addition to reducing allocations and 3097 * creating a background thread, this has the advantage that 3098 * we catch them in userdebug StrictMode reports to convert 3099 * them where possible to apply() ...) 3100 */ enqueueDiskWrite(final MemoryCommitResult mcr, final Runnable postWriteRunnable)3101 private void enqueueDiskWrite(final MemoryCommitResult mcr, 3102 final Runnable postWriteRunnable) { 3103 final Runnable writeToDiskRunnable = new Runnable() { 3104 public void run() { 3105 synchronized (mWritingToDiskLock) { 3106 writeToFile(mcr); 3107 } 3108 synchronized (SharedPreferencesImpl.this) { 3109 mDiskWritesInFlight--; 3110 } 3111 if (postWriteRunnable != null) { 3112 postWriteRunnable.run(); 3113 } 3114 } 3115 }; 3116 3117 final boolean isFromSyncCommit = (postWriteRunnable == null); 3118 3119 // Typical #commit() path with fewer allocations, doing a write on 3120 // the current thread. 3121 if (isFromSyncCommit) { 3122 boolean wasEmpty = false; 3123 synchronized (SharedPreferencesImpl.this) { 3124 wasEmpty = mDiskWritesInFlight == 1; 3125 } 3126 if (wasEmpty) { 3127 writeToDiskRunnable.run(); 3128 return; 3129 } 3130 } 3131 3132 QueuedWork.singleThreadExecutor().execute(writeToDiskRunnable); 3133 } 3134 createFileOutputStream(File file)3135 private static FileOutputStream createFileOutputStream(File file) { 3136 FileOutputStream str = null; 3137 try { 3138 str = new FileOutputStream(file); 3139 } catch (FileNotFoundException e) { 3140 File parent = file.getParentFile(); 3141 if (!parent.mkdir()) { 3142 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file); 3143 return null; 3144 } 3145 FileUtils.setPermissions( 3146 parent.getPath(), 3147 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 3148 -1, -1); 3149 try { 3150 str = new FileOutputStream(file); 3151 } catch (FileNotFoundException e2) { 3152 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2); 3153 } 3154 } 3155 return str; 3156 } 3157 3158 // Note: must hold mWritingToDiskLock writeToFile(MemoryCommitResult mcr)3159 private void writeToFile(MemoryCommitResult mcr) { 3160 // Rename the current file so it may be used as a backup during the next read 3161 if (mFile.exists()) { 3162 if (!mcr.changesMade) { 3163 // If the file already exists, but no changes were 3164 // made to the underlying map, it's wasteful to 3165 // re-write the file. Return as if we wrote it 3166 // out. 3167 mcr.setDiskWriteResult(true); 3168 return; 3169 } 3170 if (!mBackupFile.exists()) { 3171 if (!mFile.renameTo(mBackupFile)) { 3172 Log.e(TAG, "Couldn't rename file " + mFile 3173 + " to backup file " + mBackupFile); 3174 mcr.setDiskWriteResult(false); 3175 return; 3176 } 3177 } else { 3178 mFile.delete(); 3179 } 3180 } 3181 3182 // Attempt to write the file, delete the backup and return true as atomically as 3183 // possible. If any exception occurs, delete the new file; next time we will restore 3184 // from the backup. 3185 try { 3186 FileOutputStream str = createFileOutputStream(mFile); 3187 if (str == null) { 3188 mcr.setDiskWriteResult(false); 3189 return; 3190 } 3191 XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str); 3192 FileUtils.sync(str); 3193 str.close(); 3194 setFilePermissionsFromMode(mFile.getPath(), mMode, 0); 3195 FileStatus stat = new FileStatus(); 3196 if (FileUtils.getFileStatus(mFile.getPath(), stat)) { 3197 synchronized (this) { 3198 mStatTimestamp = stat.mtime; 3199 mStatSize = stat.size; 3200 } 3201 } 3202 // Writing was successful, delete the backup file if there is one. 3203 mBackupFile.delete(); 3204 mcr.setDiskWriteResult(true); 3205 return; 3206 } catch (XmlPullParserException e) { 3207 Log.w(TAG, "writeToFile: Got exception:", e); 3208 } catch (IOException e) { 3209 Log.w(TAG, "writeToFile: Got exception:", e); 3210 } 3211 // Clean up an unsuccessfully written file 3212 if (mFile.exists()) { 3213 if (!mFile.delete()) { 3214 Log.e(TAG, "Couldn't clean up partially-written file " + mFile); 3215 } 3216 } 3217 mcr.setDiskWriteResult(false); 3218 } 3219 } 3220 } 3221