PackageManagerService.java revision 44b60be189183138437a3faf9a73388af0efcf44
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.pm; 18 19import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS; 20import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 26import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 27import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 28import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 29import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 30import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 31import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 32import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 33import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 34import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 35import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 36import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 37import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 38import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 39import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 40import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 41import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 42import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 43import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 44import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 45import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 46import static android.content.pm.PackageManager.INSTALL_INTERNAL; 47import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 48import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 49import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 50import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 51import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 52import static android.content.pm.PackageManager.MATCH_ALL; 53import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 54import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 55import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 56import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 57import static android.content.pm.PackageParser.isApkFile; 58import static android.os.Process.PACKAGE_INFO_GID; 59import static android.os.Process.SYSTEM_UID; 60import static android.system.OsConstants.O_CREAT; 61import static android.system.OsConstants.O_RDWR; 62import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 63import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER; 64import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 65import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 66import static com.android.internal.util.ArrayUtils.appendInt; 67import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 68import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 69import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 70import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 71import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 72 73import android.Manifest; 74import android.app.ActivityManager; 75import android.app.ActivityManagerNative; 76import android.app.AppGlobals; 77import android.app.IActivityManager; 78import android.app.admin.IDevicePolicyManager; 79import android.app.backup.IBackupManager; 80import android.app.usage.UsageStats; 81import android.app.usage.UsageStatsManager; 82import android.content.BroadcastReceiver; 83import android.content.ComponentName; 84import android.content.Context; 85import android.content.IIntentReceiver; 86import android.content.Intent; 87import android.content.IntentFilter; 88import android.content.IntentSender; 89import android.content.IntentSender.SendIntentException; 90import android.content.ServiceConnection; 91import android.content.pm.ActivityInfo; 92import android.content.pm.ApplicationInfo; 93import android.content.pm.FeatureInfo; 94import android.content.pm.IPackageDataObserver; 95import android.content.pm.IPackageDeleteObserver; 96import android.content.pm.IPackageDeleteObserver2; 97import android.content.pm.IPackageInstallObserver2; 98import android.content.pm.IPackageInstaller; 99import android.content.pm.IPackageManager; 100import android.content.pm.IPackageMoveObserver; 101import android.content.pm.IPackageStatsObserver; 102import android.content.pm.InstrumentationInfo; 103import android.content.pm.IntentFilterVerificationInfo; 104import android.content.pm.KeySet; 105import android.content.pm.ManifestDigest; 106import android.content.pm.PackageCleanItem; 107import android.content.pm.PackageInfo; 108import android.content.pm.PackageInfoLite; 109import android.content.pm.PackageInstaller; 110import android.content.pm.PackageManager; 111import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 112import android.content.pm.PackageParser; 113import android.content.pm.PackageParser.ActivityIntentInfo; 114import android.content.pm.PackageParser.PackageLite; 115import android.content.pm.PackageParser.PackageParserException; 116import android.content.pm.PackageStats; 117import android.content.pm.PackageUserState; 118import android.content.pm.ParceledListSlice; 119import android.content.pm.PermissionGroupInfo; 120import android.content.pm.PermissionInfo; 121import android.content.pm.ProviderInfo; 122import android.content.pm.ResolveInfo; 123import android.content.pm.ServiceInfo; 124import android.content.pm.Signature; 125import android.content.pm.UserInfo; 126import android.content.pm.VerificationParams; 127import android.content.pm.VerifierDeviceIdentity; 128import android.content.pm.VerifierInfo; 129import android.content.res.Resources; 130import android.hardware.display.DisplayManager; 131import android.net.Uri; 132import android.os.Binder; 133import android.os.Build; 134import android.os.Bundle; 135import android.os.Debug; 136import android.os.Environment; 137import android.os.Environment.UserEnvironment; 138import android.os.FileUtils; 139import android.os.Handler; 140import android.os.IBinder; 141import android.os.Looper; 142import android.os.Message; 143import android.os.Parcel; 144import android.os.ParcelFileDescriptor; 145import android.os.Process; 146import android.os.RemoteCallbackList; 147import android.os.RemoteException; 148import android.os.SELinux; 149import android.os.ServiceManager; 150import android.os.SystemClock; 151import android.os.SystemProperties; 152import android.os.UserHandle; 153import android.os.UserManager; 154import android.os.storage.IMountService; 155import android.os.storage.StorageEventListener; 156import android.os.storage.StorageManager; 157import android.os.storage.VolumeInfo; 158import android.os.storage.VolumeRecord; 159import android.security.KeyStore; 160import android.security.SystemKeyStore; 161import android.system.ErrnoException; 162import android.system.Os; 163import android.system.StructStat; 164import android.text.TextUtils; 165import android.text.format.DateUtils; 166import android.util.ArrayMap; 167import android.util.ArraySet; 168import android.util.AtomicFile; 169import android.util.DisplayMetrics; 170import android.util.EventLog; 171import android.util.ExceptionUtils; 172import android.util.Log; 173import android.util.LogPrinter; 174import android.util.MathUtils; 175import android.util.PrintStreamPrinter; 176import android.util.Slog; 177import android.util.SparseArray; 178import android.util.SparseBooleanArray; 179import android.util.SparseIntArray; 180import android.util.Xml; 181import android.view.Display; 182 183import dalvik.system.DexFile; 184import dalvik.system.VMRuntime; 185 186import libcore.io.IoUtils; 187import libcore.util.EmptyArray; 188 189import com.android.internal.R; 190import com.android.internal.app.IMediaContainerService; 191import com.android.internal.app.ResolverActivity; 192import com.android.internal.content.NativeLibraryHelper; 193import com.android.internal.content.PackageHelper; 194import com.android.internal.os.IParcelFileDescriptorFactory; 195import com.android.internal.os.SomeArgs; 196import com.android.internal.util.ArrayUtils; 197import com.android.internal.util.FastPrintWriter; 198import com.android.internal.util.FastXmlSerializer; 199import com.android.internal.util.IndentingPrintWriter; 200import com.android.internal.util.Preconditions; 201import com.android.server.EventLogTags; 202import com.android.server.FgThread; 203import com.android.server.IntentResolver; 204import com.android.server.LocalServices; 205import com.android.server.ServiceThread; 206import com.android.server.SystemConfig; 207import com.android.server.Watchdog; 208import com.android.server.pm.Settings.DatabaseVersion; 209import com.android.server.storage.DeviceStorageMonitorInternal; 210 211import org.xmlpull.v1.XmlPullParser; 212import org.xmlpull.v1.XmlSerializer; 213 214import java.io.BufferedInputStream; 215import java.io.BufferedOutputStream; 216import java.io.BufferedReader; 217import java.io.ByteArrayInputStream; 218import java.io.ByteArrayOutputStream; 219import java.io.File; 220import java.io.FileDescriptor; 221import java.io.FileNotFoundException; 222import java.io.FileOutputStream; 223import java.io.FileReader; 224import java.io.FilenameFilter; 225import java.io.IOException; 226import java.io.InputStream; 227import java.io.PrintWriter; 228import java.nio.charset.StandardCharsets; 229import java.security.NoSuchAlgorithmException; 230import java.security.PublicKey; 231import java.security.cert.CertificateEncodingException; 232import java.security.cert.CertificateException; 233import java.text.SimpleDateFormat; 234import java.util.ArrayList; 235import java.util.Arrays; 236import java.util.Collection; 237import java.util.Collections; 238import java.util.Comparator; 239import java.util.Date; 240import java.util.Iterator; 241import java.util.List; 242import java.util.Map; 243import java.util.Objects; 244import java.util.Set; 245import java.util.concurrent.CountDownLatch; 246import java.util.concurrent.TimeUnit; 247import java.util.concurrent.atomic.AtomicBoolean; 248import java.util.concurrent.atomic.AtomicInteger; 249import java.util.concurrent.atomic.AtomicLong; 250 251/** 252 * Keep track of all those .apks everywhere. 253 * 254 * This is very central to the platform's security; please run the unit 255 * tests whenever making modifications here: 256 * 257mmm frameworks/base/tests/AndroidTests 258adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 259adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 260 * 261 * {@hide} 262 */ 263public class PackageManagerService extends IPackageManager.Stub { 264 static final String TAG = "PackageManager"; 265 static final boolean DEBUG_SETTINGS = false; 266 static final boolean DEBUG_PREFERRED = false; 267 static final boolean DEBUG_UPGRADE = false; 268 private static final boolean DEBUG_BACKUP = true; 269 private static final boolean DEBUG_INSTALL = false; 270 private static final boolean DEBUG_REMOVE = false; 271 private static final boolean DEBUG_BROADCASTS = false; 272 private static final boolean DEBUG_SHOW_INFO = false; 273 private static final boolean DEBUG_PACKAGE_INFO = false; 274 private static final boolean DEBUG_INTENT_MATCHING = false; 275 private static final boolean DEBUG_PACKAGE_SCANNING = false; 276 private static final boolean DEBUG_VERIFY = false; 277 private static final boolean DEBUG_DEXOPT = false; 278 private static final boolean DEBUG_ABI_SELECTION = false; 279 280 static final boolean RUNTIME_PERMISSIONS_ENABLED = true; 281 282 private static final int RADIO_UID = Process.PHONE_UID; 283 private static final int LOG_UID = Process.LOG_UID; 284 private static final int NFC_UID = Process.NFC_UID; 285 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 286 private static final int SHELL_UID = Process.SHELL_UID; 287 288 // Cap the size of permission trees that 3rd party apps can define 289 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 290 291 // Suffix used during package installation when copying/moving 292 // package apks to install directory. 293 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 294 295 static final int SCAN_NO_DEX = 1<<1; 296 static final int SCAN_FORCE_DEX = 1<<2; 297 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 298 static final int SCAN_NEW_INSTALL = 1<<4; 299 static final int SCAN_NO_PATHS = 1<<5; 300 static final int SCAN_UPDATE_TIME = 1<<6; 301 static final int SCAN_DEFER_DEX = 1<<7; 302 static final int SCAN_BOOTING = 1<<8; 303 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 304 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 305 static final int SCAN_REQUIRE_KNOWN = 1<<12; 306 307 static final int REMOVE_CHATTY = 1<<16; 308 309 /** 310 * Timeout (in milliseconds) after which the watchdog should declare that 311 * our handler thread is wedged. The usual default for such things is one 312 * minute but we sometimes do very lengthy I/O operations on this thread, 313 * such as installing multi-gigabyte applications, so ours needs to be longer. 314 */ 315 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 316 317 /** 318 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 319 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 320 * settings entry if available, otherwise we use the hardcoded default. If it's been 321 * more than this long since the last fstrim, we force one during the boot sequence. 322 * 323 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 324 * one gets run at the next available charging+idle time. This final mandatory 325 * no-fstrim check kicks in only of the other scheduling criteria is never met. 326 */ 327 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 328 329 /** 330 * Whether verification is enabled by default. 331 */ 332 private static final boolean DEFAULT_VERIFY_ENABLE = true; 333 334 /** 335 * The default maximum time to wait for the verification agent to return in 336 * milliseconds. 337 */ 338 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 339 340 /** 341 * The default response for package verification timeout. 342 * 343 * This can be either PackageManager.VERIFICATION_ALLOW or 344 * PackageManager.VERIFICATION_REJECT. 345 */ 346 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 347 348 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 349 350 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 351 DEFAULT_CONTAINER_PACKAGE, 352 "com.android.defcontainer.DefaultContainerService"); 353 354 private static final String KILL_APP_REASON_GIDS_CHANGED = 355 "permission grant or revoke changed gids"; 356 357 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 358 "permissions revoked"; 359 360 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 361 362 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 363 364 /** Permission grant: not grant the permission. */ 365 private static final int GRANT_DENIED = 1; 366 367 /** Permission grant: grant the permission as an install permission. */ 368 private static final int GRANT_INSTALL = 2; 369 370 /** Permission grant: grant the permission as a runtime one. */ 371 private static final int GRANT_RUNTIME = 3; 372 373 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 374 private static final int GRANT_UPGRADE = 4; 375 376 final ServiceThread mHandlerThread; 377 378 final PackageHandler mHandler; 379 380 /** 381 * Messages for {@link #mHandler} that need to wait for system ready before 382 * being dispatched. 383 */ 384 private ArrayList<Message> mPostSystemReadyMessages; 385 386 final int mSdkVersion = Build.VERSION.SDK_INT; 387 388 final Context mContext; 389 final boolean mFactoryTest; 390 final boolean mOnlyCore; 391 final boolean mLazyDexOpt; 392 final long mDexOptLRUThresholdInMills; 393 final DisplayMetrics mMetrics; 394 final int mDefParseFlags; 395 final String[] mSeparateProcesses; 396 final boolean mIsUpgrade; 397 398 // This is where all application persistent data goes. 399 final File mAppDataDir; 400 401 // This is where all application persistent data goes for secondary users. 402 final File mUserAppDataDir; 403 404 /** The location for ASEC container files on internal storage. */ 405 final String mAsecInternalPath; 406 407 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 408 // LOCK HELD. Can be called with mInstallLock held. 409 final Installer mInstaller; 410 411 /** Directory where installed third-party apps stored */ 412 final File mAppInstallDir; 413 414 /** 415 * Directory to which applications installed internally have their 416 * 32 bit native libraries copied. 417 */ 418 private File mAppLib32InstallDir; 419 420 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 421 // apps. 422 final File mDrmAppPrivateInstallDir; 423 424 // ---------------------------------------------------------------- 425 426 // Lock for state used when installing and doing other long running 427 // operations. Methods that must be called with this lock held have 428 // the suffix "LI". 429 final Object mInstallLock = new Object(); 430 431 // ---------------------------------------------------------------- 432 433 // Keys are String (package name), values are Package. This also serves 434 // as the lock for the global state. Methods that must be called with 435 // this lock held have the prefix "LP". 436 final ArrayMap<String, PackageParser.Package> mPackages = 437 new ArrayMap<String, PackageParser.Package>(); 438 439 // Tracks available target package names -> overlay package paths. 440 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 441 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 442 443 final Settings mSettings; 444 boolean mRestoredSettings; 445 446 // System configuration read by SystemConfig. 447 final int[] mGlobalGids; 448 final SparseArray<ArraySet<String>> mSystemPermissions; 449 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 450 451 // If mac_permissions.xml was found for seinfo labeling. 452 boolean mFoundPolicyFile; 453 454 // If a recursive restorecon of /data/data/<pkg> is needed. 455 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 456 457 public static final class SharedLibraryEntry { 458 public final String path; 459 public final String apk; 460 461 SharedLibraryEntry(String _path, String _apk) { 462 path = _path; 463 apk = _apk; 464 } 465 } 466 467 // Currently known shared libraries. 468 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 469 new ArrayMap<String, SharedLibraryEntry>(); 470 471 // All available activities, for your resolving pleasure. 472 final ActivityIntentResolver mActivities = 473 new ActivityIntentResolver(); 474 475 // All available receivers, for your resolving pleasure. 476 final ActivityIntentResolver mReceivers = 477 new ActivityIntentResolver(); 478 479 // All available services, for your resolving pleasure. 480 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 481 482 // All available providers, for your resolving pleasure. 483 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 484 485 // Mapping from provider base names (first directory in content URI codePath) 486 // to the provider information. 487 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 488 new ArrayMap<String, PackageParser.Provider>(); 489 490 // Mapping from instrumentation class names to info about them. 491 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 492 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 493 494 // Mapping from permission names to info about them. 495 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 496 new ArrayMap<String, PackageParser.PermissionGroup>(); 497 498 // Packages whose data we have transfered into another package, thus 499 // should no longer exist. 500 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 501 502 // Broadcast actions that are only available to the system. 503 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 504 505 /** List of packages waiting for verification. */ 506 final SparseArray<PackageVerificationState> mPendingVerification 507 = new SparseArray<PackageVerificationState>(); 508 509 /** Set of packages associated with each app op permission. */ 510 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 511 512 final PackageInstallerService mInstallerService; 513 514 private final PackageDexOptimizer mPackageDexOptimizer; 515 516 private AtomicInteger mNextMoveId = new AtomicInteger(); 517 private final MoveCallbacks mMoveCallbacks; 518 519 // Cache of users who need badging. 520 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 521 522 /** Token for keys in mPendingVerification. */ 523 private int mPendingVerificationToken = 0; 524 525 volatile boolean mSystemReady; 526 volatile boolean mSafeMode; 527 volatile boolean mHasSystemUidErrors; 528 529 ApplicationInfo mAndroidApplication; 530 final ActivityInfo mResolveActivity = new ActivityInfo(); 531 final ResolveInfo mResolveInfo = new ResolveInfo(); 532 ComponentName mResolveComponentName; 533 PackageParser.Package mPlatformPackage; 534 ComponentName mCustomResolverComponentName; 535 536 boolean mResolverReplaced = false; 537 538 private final ComponentName mIntentFilterVerifierComponent; 539 private int mIntentFilterVerificationToken = 0; 540 541 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 542 = new SparseArray<IntentFilterVerificationState>(); 543 544 private interface IntentFilterVerifier<T extends IntentFilter> { 545 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 546 T filter, String packageName); 547 void startVerifications(int userId); 548 void receiveVerificationResponse(int verificationId); 549 } 550 551 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 552 private Context mContext; 553 private ComponentName mIntentFilterVerifierComponent; 554 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 555 556 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 557 mContext = context; 558 mIntentFilterVerifierComponent = verifierComponent; 559 } 560 561 private String getDefaultScheme() { 562 // TODO: replace SCHEME_HTTP with SCHEME_HTTPS 563 return IntentFilter.SCHEME_HTTP; 564 } 565 566 @Override 567 public void startVerifications(int userId) { 568 // Launch verifications requests 569 int count = mCurrentIntentFilterVerifications.size(); 570 for (int n=0; n<count; n++) { 571 int verificationId = mCurrentIntentFilterVerifications.get(n); 572 final IntentFilterVerificationState ivs = 573 mIntentFilterVerificationStates.get(verificationId); 574 575 String packageName = ivs.getPackageName(); 576 577 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 578 final int filterCount = filters.size(); 579 ArraySet<String> domainsSet = new ArraySet<>(); 580 for (int m=0; m<filterCount; m++) { 581 PackageParser.ActivityIntentInfo filter = filters.get(m); 582 domainsSet.addAll(filter.getHostsList()); 583 } 584 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 585 synchronized (mPackages) { 586 if (mSettings.createIntentFilterVerificationIfNeededLPw( 587 packageName, domainsList) != null) { 588 scheduleWriteSettingsLocked(); 589 } 590 } 591 sendVerificationRequest(userId, verificationId, ivs); 592 } 593 mCurrentIntentFilterVerifications.clear(); 594 } 595 596 private void sendVerificationRequest(int userId, int verificationId, 597 IntentFilterVerificationState ivs) { 598 599 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 600 verificationIntent.putExtra( 601 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 602 verificationId); 603 verificationIntent.putExtra( 604 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 605 getDefaultScheme()); 606 verificationIntent.putExtra( 607 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 608 ivs.getHostsString()); 609 verificationIntent.putExtra( 610 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 611 ivs.getPackageName()); 612 verificationIntent.setComponent(mIntentFilterVerifierComponent); 613 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 614 615 UserHandle user = new UserHandle(userId); 616 mContext.sendBroadcastAsUser(verificationIntent, user); 617 Slog.d(TAG, "Sending IntenFilter verification broadcast"); 618 } 619 620 public void receiveVerificationResponse(int verificationId) { 621 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 622 623 final boolean verified = ivs.isVerified(); 624 625 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 626 final int count = filters.size(); 627 for (int n=0; n<count; n++) { 628 PackageParser.ActivityIntentInfo filter = filters.get(n); 629 filter.setVerified(verified); 630 631 Slog.d(TAG, "IntentFilter " + filter.toString() + " verified with result:" 632 + verified + " and hosts:" + ivs.getHostsString()); 633 } 634 635 mIntentFilterVerificationStates.remove(verificationId); 636 637 final String packageName = ivs.getPackageName(); 638 IntentFilterVerificationInfo ivi = null; 639 640 synchronized (mPackages) { 641 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 642 } 643 if (ivi == null) { 644 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 645 + verificationId + " packageName:" + packageName); 646 return; 647 } 648 Slog.d(TAG, "Updating IntentFilterVerificationInfo for verificationId:" 649 + verificationId); 650 651 synchronized (mPackages) { 652 if (verified) { 653 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 654 } else { 655 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 656 } 657 scheduleWriteSettingsLocked(); 658 659 final int userId = ivs.getUserId(); 660 if (userId != UserHandle.USER_ALL) { 661 final int userStatus = 662 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 663 664 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 665 boolean needUpdate = false; 666 667 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 668 // already been set by the User thru the Disambiguation dialog 669 switch (userStatus) { 670 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 671 if (verified) { 672 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 673 } else { 674 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 675 } 676 needUpdate = true; 677 break; 678 679 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 680 if (verified) { 681 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 682 needUpdate = true; 683 } 684 break; 685 686 default: 687 // Nothing to do 688 } 689 690 if (needUpdate) { 691 mSettings.updateIntentFilterVerificationStatusLPw( 692 packageName, updatedStatus, userId); 693 scheduleWritePackageRestrictionsLocked(userId); 694 } 695 } 696 } 697 } 698 699 @Override 700 public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 701 ActivityIntentInfo filter, String packageName) { 702 if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 703 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 704 Slog.d(TAG, "IntentFilter does not contain HTTP nor HTTPS data scheme"); 705 return false; 706 } 707 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 708 if (ivs == null) { 709 ivs = createDomainVerificationState(verifierId, userId, verificationId, 710 packageName); 711 } 712 if (!hasValidDomains(filter)) { 713 return false; 714 } 715 ivs.addFilter(filter); 716 return true; 717 } 718 719 private IntentFilterVerificationState createDomainVerificationState(int verifierId, 720 int userId, int verificationId, String packageName) { 721 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 722 verifierId, userId, packageName); 723 ivs.setPendingState(); 724 synchronized (mPackages) { 725 mIntentFilterVerificationStates.append(verificationId, ivs); 726 mCurrentIntentFilterVerifications.add(verificationId); 727 } 728 return ivs; 729 } 730 } 731 732 private static boolean hasValidDomains(ActivityIntentInfo filter) { 733 return hasValidDomains(filter, true); 734 } 735 736 private static boolean hasValidDomains(ActivityIntentInfo filter, boolean logging) { 737 boolean hasHTTPorHTTPS = filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 738 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS); 739 if (!hasHTTPorHTTPS) { 740 if (logging) { 741 Slog.d(TAG, "IntentFilter does not contain any HTTP or HTTPS data scheme"); 742 } 743 return false; 744 } 745 return true; 746 } 747 748 private IntentFilterVerifier mIntentFilterVerifier; 749 750 // Set of pending broadcasts for aggregating enable/disable of components. 751 static class PendingPackageBroadcasts { 752 // for each user id, a map of <package name -> components within that package> 753 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 754 755 public PendingPackageBroadcasts() { 756 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 757 } 758 759 public ArrayList<String> get(int userId, String packageName) { 760 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 761 return packages.get(packageName); 762 } 763 764 public void put(int userId, String packageName, ArrayList<String> components) { 765 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 766 packages.put(packageName, components); 767 } 768 769 public void remove(int userId, String packageName) { 770 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 771 if (packages != null) { 772 packages.remove(packageName); 773 } 774 } 775 776 public void remove(int userId) { 777 mUidMap.remove(userId); 778 } 779 780 public int userIdCount() { 781 return mUidMap.size(); 782 } 783 784 public int userIdAt(int n) { 785 return mUidMap.keyAt(n); 786 } 787 788 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 789 return mUidMap.get(userId); 790 } 791 792 public int size() { 793 // total number of pending broadcast entries across all userIds 794 int num = 0; 795 for (int i = 0; i< mUidMap.size(); i++) { 796 num += mUidMap.valueAt(i).size(); 797 } 798 return num; 799 } 800 801 public void clear() { 802 mUidMap.clear(); 803 } 804 805 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 806 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 807 if (map == null) { 808 map = new ArrayMap<String, ArrayList<String>>(); 809 mUidMap.put(userId, map); 810 } 811 return map; 812 } 813 } 814 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 815 816 // Service Connection to remote media container service to copy 817 // package uri's from external media onto secure containers 818 // or internal storage. 819 private IMediaContainerService mContainerService = null; 820 821 static final int SEND_PENDING_BROADCAST = 1; 822 static final int MCS_BOUND = 3; 823 static final int END_COPY = 4; 824 static final int INIT_COPY = 5; 825 static final int MCS_UNBIND = 6; 826 static final int START_CLEANING_PACKAGE = 7; 827 static final int FIND_INSTALL_LOC = 8; 828 static final int POST_INSTALL = 9; 829 static final int MCS_RECONNECT = 10; 830 static final int MCS_GIVE_UP = 11; 831 static final int UPDATED_MEDIA_STATUS = 12; 832 static final int WRITE_SETTINGS = 13; 833 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 834 static final int PACKAGE_VERIFIED = 15; 835 static final int CHECK_PENDING_VERIFICATION = 16; 836 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 837 static final int INTENT_FILTER_VERIFIED = 18; 838 839 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 840 841 // Delay time in millisecs 842 static final int BROADCAST_DELAY = 10 * 1000; 843 844 static UserManagerService sUserManager; 845 846 // Stores a list of users whose package restrictions file needs to be updated 847 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 848 849 final private DefaultContainerConnection mDefContainerConn = 850 new DefaultContainerConnection(); 851 class DefaultContainerConnection implements ServiceConnection { 852 public void onServiceConnected(ComponentName name, IBinder service) { 853 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 854 IMediaContainerService imcs = 855 IMediaContainerService.Stub.asInterface(service); 856 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 857 } 858 859 public void onServiceDisconnected(ComponentName name) { 860 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 861 } 862 }; 863 864 // Recordkeeping of restore-after-install operations that are currently in flight 865 // between the Package Manager and the Backup Manager 866 class PostInstallData { 867 public InstallArgs args; 868 public PackageInstalledInfo res; 869 870 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 871 args = _a; 872 res = _r; 873 } 874 }; 875 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 876 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 877 878 // backup/restore of preferred activity state 879 private static final String TAG_PREFERRED_BACKUP = "pa"; 880 881 private final String mRequiredVerifierPackage; 882 883 private final PackageUsage mPackageUsage = new PackageUsage(); 884 885 private class PackageUsage { 886 private static final int WRITE_INTERVAL 887 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 888 889 private final Object mFileLock = new Object(); 890 private final AtomicLong mLastWritten = new AtomicLong(0); 891 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 892 893 private boolean mIsHistoricalPackageUsageAvailable = true; 894 895 boolean isHistoricalPackageUsageAvailable() { 896 return mIsHistoricalPackageUsageAvailable; 897 } 898 899 void write(boolean force) { 900 if (force) { 901 writeInternal(); 902 return; 903 } 904 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 905 && !DEBUG_DEXOPT) { 906 return; 907 } 908 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 909 new Thread("PackageUsage_DiskWriter") { 910 @Override 911 public void run() { 912 try { 913 writeInternal(); 914 } finally { 915 mBackgroundWriteRunning.set(false); 916 } 917 } 918 }.start(); 919 } 920 } 921 922 private void writeInternal() { 923 synchronized (mPackages) { 924 synchronized (mFileLock) { 925 AtomicFile file = getFile(); 926 FileOutputStream f = null; 927 try { 928 f = file.startWrite(); 929 BufferedOutputStream out = new BufferedOutputStream(f); 930 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 931 StringBuilder sb = new StringBuilder(); 932 for (PackageParser.Package pkg : mPackages.values()) { 933 if (pkg.mLastPackageUsageTimeInMills == 0) { 934 continue; 935 } 936 sb.setLength(0); 937 sb.append(pkg.packageName); 938 sb.append(' '); 939 sb.append((long)pkg.mLastPackageUsageTimeInMills); 940 sb.append('\n'); 941 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 942 } 943 out.flush(); 944 file.finishWrite(f); 945 } catch (IOException e) { 946 if (f != null) { 947 file.failWrite(f); 948 } 949 Log.e(TAG, "Failed to write package usage times", e); 950 } 951 } 952 } 953 mLastWritten.set(SystemClock.elapsedRealtime()); 954 } 955 956 void readLP() { 957 synchronized (mFileLock) { 958 AtomicFile file = getFile(); 959 BufferedInputStream in = null; 960 try { 961 in = new BufferedInputStream(file.openRead()); 962 StringBuffer sb = new StringBuffer(); 963 while (true) { 964 String packageName = readToken(in, sb, ' '); 965 if (packageName == null) { 966 break; 967 } 968 String timeInMillisString = readToken(in, sb, '\n'); 969 if (timeInMillisString == null) { 970 throw new IOException("Failed to find last usage time for package " 971 + packageName); 972 } 973 PackageParser.Package pkg = mPackages.get(packageName); 974 if (pkg == null) { 975 continue; 976 } 977 long timeInMillis; 978 try { 979 timeInMillis = Long.parseLong(timeInMillisString.toString()); 980 } catch (NumberFormatException e) { 981 throw new IOException("Failed to parse " + timeInMillisString 982 + " as a long.", e); 983 } 984 pkg.mLastPackageUsageTimeInMills = timeInMillis; 985 } 986 } catch (FileNotFoundException expected) { 987 mIsHistoricalPackageUsageAvailable = false; 988 } catch (IOException e) { 989 Log.w(TAG, "Failed to read package usage times", e); 990 } finally { 991 IoUtils.closeQuietly(in); 992 } 993 } 994 mLastWritten.set(SystemClock.elapsedRealtime()); 995 } 996 997 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 998 throws IOException { 999 sb.setLength(0); 1000 while (true) { 1001 int ch = in.read(); 1002 if (ch == -1) { 1003 if (sb.length() == 0) { 1004 return null; 1005 } 1006 throw new IOException("Unexpected EOF"); 1007 } 1008 if (ch == endOfToken) { 1009 return sb.toString(); 1010 } 1011 sb.append((char)ch); 1012 } 1013 } 1014 1015 private AtomicFile getFile() { 1016 File dataDir = Environment.getDataDirectory(); 1017 File systemDir = new File(dataDir, "system"); 1018 File fname = new File(systemDir, "package-usage.list"); 1019 return new AtomicFile(fname); 1020 } 1021 } 1022 1023 class PackageHandler extends Handler { 1024 private boolean mBound = false; 1025 final ArrayList<HandlerParams> mPendingInstalls = 1026 new ArrayList<HandlerParams>(); 1027 1028 private boolean connectToService() { 1029 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1030 " DefaultContainerService"); 1031 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1032 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1033 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1034 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 1035 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1036 mBound = true; 1037 return true; 1038 } 1039 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1040 return false; 1041 } 1042 1043 private void disconnectService() { 1044 mContainerService = null; 1045 mBound = false; 1046 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1047 mContext.unbindService(mDefContainerConn); 1048 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1049 } 1050 1051 PackageHandler(Looper looper) { 1052 super(looper); 1053 } 1054 1055 public void handleMessage(Message msg) { 1056 try { 1057 doHandleMessage(msg); 1058 } finally { 1059 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1060 } 1061 } 1062 1063 void doHandleMessage(Message msg) { 1064 switch (msg.what) { 1065 case INIT_COPY: { 1066 HandlerParams params = (HandlerParams) msg.obj; 1067 int idx = mPendingInstalls.size(); 1068 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1069 // If a bind was already initiated we dont really 1070 // need to do anything. The pending install 1071 // will be processed later on. 1072 if (!mBound) { 1073 // If this is the only one pending we might 1074 // have to bind to the service again. 1075 if (!connectToService()) { 1076 Slog.e(TAG, "Failed to bind to media container service"); 1077 params.serviceError(); 1078 return; 1079 } else { 1080 // Once we bind to the service, the first 1081 // pending request will be processed. 1082 mPendingInstalls.add(idx, params); 1083 } 1084 } else { 1085 mPendingInstalls.add(idx, params); 1086 // Already bound to the service. Just make 1087 // sure we trigger off processing the first request. 1088 if (idx == 0) { 1089 mHandler.sendEmptyMessage(MCS_BOUND); 1090 } 1091 } 1092 break; 1093 } 1094 case MCS_BOUND: { 1095 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1096 if (msg.obj != null) { 1097 mContainerService = (IMediaContainerService) msg.obj; 1098 } 1099 if (mContainerService == null) { 1100 // Something seriously wrong. Bail out 1101 Slog.e(TAG, "Cannot bind to media container service"); 1102 for (HandlerParams params : mPendingInstalls) { 1103 // Indicate service bind error 1104 params.serviceError(); 1105 } 1106 mPendingInstalls.clear(); 1107 } else if (mPendingInstalls.size() > 0) { 1108 HandlerParams params = mPendingInstalls.get(0); 1109 if (params != null) { 1110 if (params.startCopy()) { 1111 // We are done... look for more work or to 1112 // go idle. 1113 if (DEBUG_SD_INSTALL) Log.i(TAG, 1114 "Checking for more work or unbind..."); 1115 // Delete pending install 1116 if (mPendingInstalls.size() > 0) { 1117 mPendingInstalls.remove(0); 1118 } 1119 if (mPendingInstalls.size() == 0) { 1120 if (mBound) { 1121 if (DEBUG_SD_INSTALL) Log.i(TAG, 1122 "Posting delayed MCS_UNBIND"); 1123 removeMessages(MCS_UNBIND); 1124 Message ubmsg = obtainMessage(MCS_UNBIND); 1125 // Unbind after a little delay, to avoid 1126 // continual thrashing. 1127 sendMessageDelayed(ubmsg, 10000); 1128 } 1129 } else { 1130 // There are more pending requests in queue. 1131 // Just post MCS_BOUND message to trigger processing 1132 // of next pending install. 1133 if (DEBUG_SD_INSTALL) Log.i(TAG, 1134 "Posting MCS_BOUND for next work"); 1135 mHandler.sendEmptyMessage(MCS_BOUND); 1136 } 1137 } 1138 } 1139 } else { 1140 // Should never happen ideally. 1141 Slog.w(TAG, "Empty queue"); 1142 } 1143 break; 1144 } 1145 case MCS_RECONNECT: { 1146 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1147 if (mPendingInstalls.size() > 0) { 1148 if (mBound) { 1149 disconnectService(); 1150 } 1151 if (!connectToService()) { 1152 Slog.e(TAG, "Failed to bind to media container service"); 1153 for (HandlerParams params : mPendingInstalls) { 1154 // Indicate service bind error 1155 params.serviceError(); 1156 } 1157 mPendingInstalls.clear(); 1158 } 1159 } 1160 break; 1161 } 1162 case MCS_UNBIND: { 1163 // If there is no actual work left, then time to unbind. 1164 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1165 1166 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1167 if (mBound) { 1168 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1169 1170 disconnectService(); 1171 } 1172 } else if (mPendingInstalls.size() > 0) { 1173 // There are more pending requests in queue. 1174 // Just post MCS_BOUND message to trigger processing 1175 // of next pending install. 1176 mHandler.sendEmptyMessage(MCS_BOUND); 1177 } 1178 1179 break; 1180 } 1181 case MCS_GIVE_UP: { 1182 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1183 mPendingInstalls.remove(0); 1184 break; 1185 } 1186 case SEND_PENDING_BROADCAST: { 1187 String packages[]; 1188 ArrayList<String> components[]; 1189 int size = 0; 1190 int uids[]; 1191 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1192 synchronized (mPackages) { 1193 if (mPendingBroadcasts == null) { 1194 return; 1195 } 1196 size = mPendingBroadcasts.size(); 1197 if (size <= 0) { 1198 // Nothing to be done. Just return 1199 return; 1200 } 1201 packages = new String[size]; 1202 components = new ArrayList[size]; 1203 uids = new int[size]; 1204 int i = 0; // filling out the above arrays 1205 1206 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1207 int packageUserId = mPendingBroadcasts.userIdAt(n); 1208 Iterator<Map.Entry<String, ArrayList<String>>> it 1209 = mPendingBroadcasts.packagesForUserId(packageUserId) 1210 .entrySet().iterator(); 1211 while (it.hasNext() && i < size) { 1212 Map.Entry<String, ArrayList<String>> ent = it.next(); 1213 packages[i] = ent.getKey(); 1214 components[i] = ent.getValue(); 1215 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1216 uids[i] = (ps != null) 1217 ? UserHandle.getUid(packageUserId, ps.appId) 1218 : -1; 1219 i++; 1220 } 1221 } 1222 size = i; 1223 mPendingBroadcasts.clear(); 1224 } 1225 // Send broadcasts 1226 for (int i = 0; i < size; i++) { 1227 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1228 } 1229 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1230 break; 1231 } 1232 case START_CLEANING_PACKAGE: { 1233 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1234 final String packageName = (String)msg.obj; 1235 final int userId = msg.arg1; 1236 final boolean andCode = msg.arg2 != 0; 1237 synchronized (mPackages) { 1238 if (userId == UserHandle.USER_ALL) { 1239 int[] users = sUserManager.getUserIds(); 1240 for (int user : users) { 1241 mSettings.addPackageToCleanLPw( 1242 new PackageCleanItem(user, packageName, andCode)); 1243 } 1244 } else { 1245 mSettings.addPackageToCleanLPw( 1246 new PackageCleanItem(userId, packageName, andCode)); 1247 } 1248 } 1249 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1250 startCleaningPackages(); 1251 } break; 1252 case POST_INSTALL: { 1253 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1254 PostInstallData data = mRunningInstalls.get(msg.arg1); 1255 mRunningInstalls.delete(msg.arg1); 1256 boolean deleteOld = false; 1257 1258 if (data != null) { 1259 InstallArgs args = data.args; 1260 PackageInstalledInfo res = data.res; 1261 1262 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1263 res.removedInfo.sendBroadcast(false, true, false); 1264 Bundle extras = new Bundle(1); 1265 extras.putInt(Intent.EXTRA_UID, res.uid); 1266 1267 // Now that we successfully installed the package, grant runtime 1268 // permissions if requested before broadcasting the install. 1269 if ((args.installFlags 1270 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { 1271 grantRequestedRuntimePermissions(res.pkg, 1272 args.user.getIdentifier()); 1273 } 1274 1275 // Determine the set of users who are adding this 1276 // package for the first time vs. those who are seeing 1277 // an update. 1278 int[] firstUsers; 1279 int[] updateUsers = new int[0]; 1280 if (res.origUsers == null || res.origUsers.length == 0) { 1281 firstUsers = res.newUsers; 1282 } else { 1283 firstUsers = new int[0]; 1284 for (int i=0; i<res.newUsers.length; i++) { 1285 int user = res.newUsers[i]; 1286 boolean isNew = true; 1287 for (int j=0; j<res.origUsers.length; j++) { 1288 if (res.origUsers[j] == user) { 1289 isNew = false; 1290 break; 1291 } 1292 } 1293 if (isNew) { 1294 int[] newFirst = new int[firstUsers.length+1]; 1295 System.arraycopy(firstUsers, 0, newFirst, 0, 1296 firstUsers.length); 1297 newFirst[firstUsers.length] = user; 1298 firstUsers = newFirst; 1299 } else { 1300 int[] newUpdate = new int[updateUsers.length+1]; 1301 System.arraycopy(updateUsers, 0, newUpdate, 0, 1302 updateUsers.length); 1303 newUpdate[updateUsers.length] = user; 1304 updateUsers = newUpdate; 1305 } 1306 } 1307 } 1308 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1309 res.pkg.applicationInfo.packageName, 1310 extras, null, null, firstUsers); 1311 final boolean update = res.removedInfo.removedPackage != null; 1312 if (update) { 1313 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1314 } 1315 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1316 res.pkg.applicationInfo.packageName, 1317 extras, null, null, updateUsers); 1318 if (update) { 1319 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1320 res.pkg.applicationInfo.packageName, 1321 extras, null, null, updateUsers); 1322 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1323 null, null, 1324 res.pkg.applicationInfo.packageName, null, updateUsers); 1325 1326 // treat asec-hosted packages like removable media on upgrade 1327 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1328 if (DEBUG_INSTALL) { 1329 Slog.i(TAG, "upgrading pkg " + res.pkg 1330 + " is ASEC-hosted -> AVAILABLE"); 1331 } 1332 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1333 ArrayList<String> pkgList = new ArrayList<String>(1); 1334 pkgList.add(res.pkg.applicationInfo.packageName); 1335 sendResourcesChangedBroadcast(true, true, 1336 pkgList,uidArray, null); 1337 } 1338 } 1339 if (res.removedInfo.args != null) { 1340 // Remove the replaced package's older resources safely now 1341 deleteOld = true; 1342 } 1343 1344 // Log current value of "unknown sources" setting 1345 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1346 getUnknownSourcesSettings()); 1347 } 1348 // Force a gc to clear up things 1349 Runtime.getRuntime().gc(); 1350 // We delete after a gc for applications on sdcard. 1351 if (deleteOld) { 1352 synchronized (mInstallLock) { 1353 res.removedInfo.args.doPostDeleteLI(true); 1354 } 1355 } 1356 if (args.observer != null) { 1357 try { 1358 Bundle extras = extrasForInstallResult(res); 1359 args.observer.onPackageInstalled(res.name, res.returnCode, 1360 res.returnMsg, extras); 1361 } catch (RemoteException e) { 1362 Slog.i(TAG, "Observer no longer exists."); 1363 } 1364 } 1365 } else { 1366 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1367 } 1368 } break; 1369 case UPDATED_MEDIA_STATUS: { 1370 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1371 boolean reportStatus = msg.arg1 == 1; 1372 boolean doGc = msg.arg2 == 1; 1373 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1374 if (doGc) { 1375 // Force a gc to clear up stale containers. 1376 Runtime.getRuntime().gc(); 1377 } 1378 if (msg.obj != null) { 1379 @SuppressWarnings("unchecked") 1380 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1381 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1382 // Unload containers 1383 unloadAllContainers(args); 1384 } 1385 if (reportStatus) { 1386 try { 1387 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1388 PackageHelper.getMountService().finishMediaUpdate(); 1389 } catch (RemoteException e) { 1390 Log.e(TAG, "MountService not running?"); 1391 } 1392 } 1393 } break; 1394 case WRITE_SETTINGS: { 1395 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1396 synchronized (mPackages) { 1397 removeMessages(WRITE_SETTINGS); 1398 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1399 mSettings.writeLPr(); 1400 mDirtyUsers.clear(); 1401 } 1402 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1403 } break; 1404 case WRITE_PACKAGE_RESTRICTIONS: { 1405 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1406 synchronized (mPackages) { 1407 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1408 for (int userId : mDirtyUsers) { 1409 mSettings.writePackageRestrictionsLPr(userId); 1410 } 1411 mDirtyUsers.clear(); 1412 } 1413 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1414 } break; 1415 case CHECK_PENDING_VERIFICATION: { 1416 final int verificationId = msg.arg1; 1417 final PackageVerificationState state = mPendingVerification.get(verificationId); 1418 1419 if ((state != null) && !state.timeoutExtended()) { 1420 final InstallArgs args = state.getInstallArgs(); 1421 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1422 1423 Slog.i(TAG, "Verification timed out for " + originUri); 1424 mPendingVerification.remove(verificationId); 1425 1426 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1427 1428 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1429 Slog.i(TAG, "Continuing with installation of " + originUri); 1430 state.setVerifierResponse(Binder.getCallingUid(), 1431 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1432 broadcastPackageVerified(verificationId, originUri, 1433 PackageManager.VERIFICATION_ALLOW, 1434 state.getInstallArgs().getUser()); 1435 try { 1436 ret = args.copyApk(mContainerService, true); 1437 } catch (RemoteException e) { 1438 Slog.e(TAG, "Could not contact the ContainerService"); 1439 } 1440 } else { 1441 broadcastPackageVerified(verificationId, originUri, 1442 PackageManager.VERIFICATION_REJECT, 1443 state.getInstallArgs().getUser()); 1444 } 1445 1446 processPendingInstall(args, ret); 1447 mHandler.sendEmptyMessage(MCS_UNBIND); 1448 } 1449 break; 1450 } 1451 case PACKAGE_VERIFIED: { 1452 final int verificationId = msg.arg1; 1453 1454 final PackageVerificationState state = mPendingVerification.get(verificationId); 1455 if (state == null) { 1456 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1457 break; 1458 } 1459 1460 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1461 1462 state.setVerifierResponse(response.callerUid, response.code); 1463 1464 if (state.isVerificationComplete()) { 1465 mPendingVerification.remove(verificationId); 1466 1467 final InstallArgs args = state.getInstallArgs(); 1468 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1469 1470 int ret; 1471 if (state.isInstallAllowed()) { 1472 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1473 broadcastPackageVerified(verificationId, originUri, 1474 response.code, state.getInstallArgs().getUser()); 1475 try { 1476 ret = args.copyApk(mContainerService, true); 1477 } catch (RemoteException e) { 1478 Slog.e(TAG, "Could not contact the ContainerService"); 1479 } 1480 } else { 1481 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1482 } 1483 1484 processPendingInstall(args, ret); 1485 1486 mHandler.sendEmptyMessage(MCS_UNBIND); 1487 } 1488 1489 break; 1490 } 1491 case START_INTENT_FILTER_VERIFICATIONS: { 1492 int userId = msg.arg1; 1493 int verifierUid = msg.arg2; 1494 PackageParser.Package pkg = (PackageParser.Package)msg.obj; 1495 1496 verifyIntentFiltersIfNeeded(userId, verifierUid, pkg); 1497 break; 1498 } 1499 case INTENT_FILTER_VERIFIED: { 1500 final int verificationId = msg.arg1; 1501 1502 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1503 verificationId); 1504 if (state == null) { 1505 Slog.w(TAG, "Invalid IntentFilter verification token " 1506 + verificationId + " received"); 1507 break; 1508 } 1509 1510 final int userId = state.getUserId(); 1511 1512 Slog.d(TAG, "Processing IntentFilter verification with token:" 1513 + verificationId + " and userId:" + userId); 1514 1515 final IntentFilterVerificationResponse response = 1516 (IntentFilterVerificationResponse) msg.obj; 1517 1518 state.setVerifierResponse(response.callerUid, response.code); 1519 1520 Slog.d(TAG, "IntentFilter verification with token:" + verificationId 1521 + " and userId:" + userId 1522 + " is settings verifier response with response code:" 1523 + response.code); 1524 1525 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1526 Slog.d(TAG, "Domains failing verification: " 1527 + response.getFailedDomainsString()); 1528 } 1529 1530 if (state.isVerificationComplete()) { 1531 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1532 } else { 1533 Slog.d(TAG, "IntentFilter verification with token:" + verificationId 1534 + " was not said to be complete"); 1535 } 1536 1537 break; 1538 } 1539 } 1540 } 1541 } 1542 1543 private StorageEventListener mStorageListener = new StorageEventListener() { 1544 @Override 1545 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1546 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1547 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1548 // TODO: ensure that private directories exist for all active users 1549 // TODO: remove user data whose serial number doesn't match 1550 loadPrivatePackages(vol); 1551 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1552 unloadPrivatePackages(vol); 1553 } 1554 } 1555 1556 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1557 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1558 updateExternalMediaStatus(true, false); 1559 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1560 updateExternalMediaStatus(false, false); 1561 } 1562 } 1563 } 1564 1565 @Override 1566 public void onVolumeForgotten(String fsUuid) { 1567 // TODO: remove all packages hosted on this uuid 1568 } 1569 }; 1570 1571 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) { 1572 if (userId >= UserHandle.USER_OWNER) { 1573 grantRequestedRuntimePermissionsForUser(pkg, userId); 1574 } else if (userId == UserHandle.USER_ALL) { 1575 for (int someUserId : UserManagerService.getInstance().getUserIds()) { 1576 grantRequestedRuntimePermissionsForUser(pkg, someUserId); 1577 } 1578 } 1579 } 1580 1581 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) { 1582 SettingBase sb = (SettingBase) pkg.mExtras; 1583 if (sb == null) { 1584 return; 1585 } 1586 1587 PermissionsState permissionsState = sb.getPermissionsState(); 1588 1589 for (String permission : pkg.requestedPermissions) { 1590 BasePermission bp = mSettings.mPermissions.get(permission); 1591 if (bp != null && bp.isRuntime()) { 1592 permissionsState.grantRuntimePermission(bp, userId); 1593 } 1594 } 1595 } 1596 1597 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1598 Bundle extras = null; 1599 switch (res.returnCode) { 1600 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1601 extras = new Bundle(); 1602 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1603 res.origPermission); 1604 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1605 res.origPackage); 1606 break; 1607 } 1608 case PackageManager.INSTALL_SUCCEEDED: { 1609 extras = new Bundle(); 1610 extras.putBoolean(Intent.EXTRA_REPLACING, 1611 res.removedInfo != null && res.removedInfo.removedPackage != null); 1612 break; 1613 } 1614 } 1615 return extras; 1616 } 1617 1618 void scheduleWriteSettingsLocked() { 1619 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1620 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1621 } 1622 } 1623 1624 void scheduleWritePackageRestrictionsLocked(int userId) { 1625 if (!sUserManager.exists(userId)) return; 1626 mDirtyUsers.add(userId); 1627 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1628 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1629 } 1630 } 1631 1632 public static PackageManagerService main(Context context, Installer installer, 1633 boolean factoryTest, boolean onlyCore) { 1634 PackageManagerService m = new PackageManagerService(context, installer, 1635 factoryTest, onlyCore); 1636 ServiceManager.addService("package", m); 1637 return m; 1638 } 1639 1640 static String[] splitString(String str, char sep) { 1641 int count = 1; 1642 int i = 0; 1643 while ((i=str.indexOf(sep, i)) >= 0) { 1644 count++; 1645 i++; 1646 } 1647 1648 String[] res = new String[count]; 1649 i=0; 1650 count = 0; 1651 int lastI=0; 1652 while ((i=str.indexOf(sep, i)) >= 0) { 1653 res[count] = str.substring(lastI, i); 1654 count++; 1655 i++; 1656 lastI = i; 1657 } 1658 res[count] = str.substring(lastI, str.length()); 1659 return res; 1660 } 1661 1662 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1663 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1664 Context.DISPLAY_SERVICE); 1665 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1666 } 1667 1668 public PackageManagerService(Context context, Installer installer, 1669 boolean factoryTest, boolean onlyCore) { 1670 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1671 SystemClock.uptimeMillis()); 1672 1673 if (mSdkVersion <= 0) { 1674 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1675 } 1676 1677 mContext = context; 1678 mFactoryTest = factoryTest; 1679 mOnlyCore = onlyCore; 1680 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1681 mMetrics = new DisplayMetrics(); 1682 mSettings = new Settings(mPackages); 1683 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1684 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1685 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1686 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1687 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1688 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1689 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1690 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1691 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1692 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1693 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1694 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1695 1696 // TODO: add a property to control this? 1697 long dexOptLRUThresholdInMinutes; 1698 if (mLazyDexOpt) { 1699 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1700 } else { 1701 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1702 } 1703 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1704 1705 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1706 if (separateProcesses != null && separateProcesses.length() > 0) { 1707 if ("*".equals(separateProcesses)) { 1708 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1709 mSeparateProcesses = null; 1710 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1711 } else { 1712 mDefParseFlags = 0; 1713 mSeparateProcesses = separateProcesses.split(","); 1714 Slog.w(TAG, "Running with debug.separate_processes: " 1715 + separateProcesses); 1716 } 1717 } else { 1718 mDefParseFlags = 0; 1719 mSeparateProcesses = null; 1720 } 1721 1722 mInstaller = installer; 1723 mPackageDexOptimizer = new PackageDexOptimizer(this); 1724 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 1725 1726 getDefaultDisplayMetrics(context, mMetrics); 1727 1728 SystemConfig systemConfig = SystemConfig.getInstance(); 1729 mGlobalGids = systemConfig.getGlobalGids(); 1730 mSystemPermissions = systemConfig.getSystemPermissions(); 1731 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1732 1733 synchronized (mInstallLock) { 1734 // writer 1735 synchronized (mPackages) { 1736 mHandlerThread = new ServiceThread(TAG, 1737 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1738 mHandlerThread.start(); 1739 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1740 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1741 1742 File dataDir = Environment.getDataDirectory(); 1743 mAppDataDir = new File(dataDir, "data"); 1744 mAppInstallDir = new File(dataDir, "app"); 1745 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1746 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1747 mUserAppDataDir = new File(dataDir, "user"); 1748 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1749 1750 sUserManager = new UserManagerService(context, this, 1751 mInstallLock, mPackages); 1752 1753 // Propagate permission configuration in to package manager. 1754 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1755 = systemConfig.getPermissions(); 1756 for (int i=0; i<permConfig.size(); i++) { 1757 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1758 BasePermission bp = mSettings.mPermissions.get(perm.name); 1759 if (bp == null) { 1760 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1761 mSettings.mPermissions.put(perm.name, bp); 1762 } 1763 if (perm.gids != null) { 1764 bp.setGids(perm.gids, perm.perUser); 1765 } 1766 } 1767 1768 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1769 for (int i=0; i<libConfig.size(); i++) { 1770 mSharedLibraries.put(libConfig.keyAt(i), 1771 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1772 } 1773 1774 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1775 1776 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1777 mSdkVersion, mOnlyCore); 1778 1779 String customResolverActivity = Resources.getSystem().getString( 1780 R.string.config_customResolverActivity); 1781 if (TextUtils.isEmpty(customResolverActivity)) { 1782 customResolverActivity = null; 1783 } else { 1784 mCustomResolverComponentName = ComponentName.unflattenFromString( 1785 customResolverActivity); 1786 } 1787 1788 long startTime = SystemClock.uptimeMillis(); 1789 1790 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1791 startTime); 1792 1793 // Set flag to monitor and not change apk file paths when 1794 // scanning install directories. 1795 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1796 1797 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1798 1799 /** 1800 * Add everything in the in the boot class path to the 1801 * list of process files because dexopt will have been run 1802 * if necessary during zygote startup. 1803 */ 1804 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1805 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1806 1807 if (bootClassPath != null) { 1808 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1809 for (String element : bootClassPathElements) { 1810 alreadyDexOpted.add(element); 1811 } 1812 } else { 1813 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1814 } 1815 1816 if (systemServerClassPath != null) { 1817 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1818 for (String element : systemServerClassPathElements) { 1819 alreadyDexOpted.add(element); 1820 } 1821 } else { 1822 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 1823 } 1824 1825 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 1826 final String[] dexCodeInstructionSets = 1827 getDexCodeInstructionSets( 1828 allInstructionSets.toArray(new String[allInstructionSets.size()])); 1829 1830 /** 1831 * Ensure all external libraries have had dexopt run on them. 1832 */ 1833 if (mSharedLibraries.size() > 0) { 1834 // NOTE: For now, we're compiling these system "shared libraries" 1835 // (and framework jars) into all available architectures. It's possible 1836 // to compile them only when we come across an app that uses them (there's 1837 // already logic for that in scanPackageLI) but that adds some complexity. 1838 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1839 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1840 final String lib = libEntry.path; 1841 if (lib == null) { 1842 continue; 1843 } 1844 1845 try { 1846 int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); 1847 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1848 alreadyDexOpted.add(lib); 1849 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 1850 } 1851 } catch (FileNotFoundException e) { 1852 Slog.w(TAG, "Library not found: " + lib); 1853 } catch (IOException e) { 1854 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1855 + e.getMessage()); 1856 } 1857 } 1858 } 1859 } 1860 1861 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1862 1863 // Gross hack for now: we know this file doesn't contain any 1864 // code, so don't dexopt it to avoid the resulting log spew. 1865 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1866 1867 // Gross hack for now: we know this file is only part of 1868 // the boot class path for art, so don't dexopt it to 1869 // avoid the resulting log spew. 1870 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1871 1872 /** 1873 * And there are a number of commands implemented in Java, which 1874 * we currently need to do the dexopt on so that they can be 1875 * run from a non-root shell. 1876 */ 1877 String[] frameworkFiles = frameworkDir.list(); 1878 if (frameworkFiles != null) { 1879 // TODO: We could compile these only for the most preferred ABI. We should 1880 // first double check that the dex files for these commands are not referenced 1881 // by other system apps. 1882 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1883 for (int i=0; i<frameworkFiles.length; i++) { 1884 File libPath = new File(frameworkDir, frameworkFiles[i]); 1885 String path = libPath.getPath(); 1886 // Skip the file if we already did it. 1887 if (alreadyDexOpted.contains(path)) { 1888 continue; 1889 } 1890 // Skip the file if it is not a type we want to dexopt. 1891 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1892 continue; 1893 } 1894 try { 1895 int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); 1896 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1897 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 1898 } 1899 } catch (FileNotFoundException e) { 1900 Slog.w(TAG, "Jar not found: " + path); 1901 } catch (IOException e) { 1902 Slog.w(TAG, "Exception reading jar: " + path, e); 1903 } 1904 } 1905 } 1906 } 1907 1908 // Collect vendor overlay packages. 1909 // (Do this before scanning any apps.) 1910 // For security and version matching reason, only consider 1911 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1912 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1913 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1914 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 1915 1916 // Find base frameworks (resource packages without code). 1917 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1918 | PackageParser.PARSE_IS_SYSTEM_DIR 1919 | PackageParser.PARSE_IS_PRIVILEGED, 1920 scanFlags | SCAN_NO_DEX, 0); 1921 1922 // Collected privileged system packages. 1923 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1924 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1925 | PackageParser.PARSE_IS_SYSTEM_DIR 1926 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 1927 1928 // Collect ordinary system packages. 1929 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1930 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1931 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1932 1933 // Collect all vendor packages. 1934 File vendorAppDir = new File("/vendor/app"); 1935 try { 1936 vendorAppDir = vendorAppDir.getCanonicalFile(); 1937 } catch (IOException e) { 1938 // failed to look up canonical path, continue with original one 1939 } 1940 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1941 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1942 1943 // Collect all OEM packages. 1944 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 1945 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 1946 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1947 1948 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1949 mInstaller.moveFiles(); 1950 1951 // Prune any system packages that no longer exist. 1952 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1953 final ArrayMap<String, File> expectingBetter = new ArrayMap<>(); 1954 if (!mOnlyCore) { 1955 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1956 while (psit.hasNext()) { 1957 PackageSetting ps = psit.next(); 1958 1959 /* 1960 * If this is not a system app, it can't be a 1961 * disable system app. 1962 */ 1963 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1964 continue; 1965 } 1966 1967 /* 1968 * If the package is scanned, it's not erased. 1969 */ 1970 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1971 if (scannedPkg != null) { 1972 /* 1973 * If the system app is both scanned and in the 1974 * disabled packages list, then it must have been 1975 * added via OTA. Remove it from the currently 1976 * scanned package so the previously user-installed 1977 * application can be scanned. 1978 */ 1979 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1980 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 1981 + ps.name + "; removing system app. Last known codePath=" 1982 + ps.codePathString + ", installStatus=" + ps.installStatus 1983 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 1984 + scannedPkg.mVersionCode); 1985 removePackageLI(ps, true); 1986 expectingBetter.put(ps.name, ps.codePath); 1987 } 1988 1989 continue; 1990 } 1991 1992 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 1993 psit.remove(); 1994 logCriticalInfo(Log.WARN, "System package " + ps.name 1995 + " no longer exists; wiping its data"); 1996 removeDataDirsLI(null, ps.name); 1997 } else { 1998 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 1999 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2000 possiblyDeletedUpdatedSystemApps.add(ps.name); 2001 } 2002 } 2003 } 2004 } 2005 2006 //look for any incomplete package installations 2007 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2008 //clean up list 2009 for(int i = 0; i < deletePkgsList.size(); i++) { 2010 //clean up here 2011 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2012 } 2013 //delete tmp files 2014 deleteTempPackageFiles(); 2015 2016 // Remove any shared userIDs that have no associated packages 2017 mSettings.pruneSharedUsersLPw(); 2018 2019 if (!mOnlyCore) { 2020 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2021 SystemClock.uptimeMillis()); 2022 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2023 2024 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2025 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2026 2027 /** 2028 * Remove disable package settings for any updated system 2029 * apps that were removed via an OTA. If they're not a 2030 * previously-updated app, remove them completely. 2031 * Otherwise, just revoke their system-level permissions. 2032 */ 2033 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2034 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2035 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2036 2037 String msg; 2038 if (deletedPkg == null) { 2039 msg = "Updated system package " + deletedAppName 2040 + " no longer exists; wiping its data"; 2041 removeDataDirsLI(null, deletedAppName); 2042 } else { 2043 msg = "Updated system app + " + deletedAppName 2044 + " no longer present; removing system privileges for " 2045 + deletedAppName; 2046 2047 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2048 2049 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2050 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2051 } 2052 logCriticalInfo(Log.WARN, msg); 2053 } 2054 2055 /** 2056 * Make sure all system apps that we expected to appear on 2057 * the userdata partition actually showed up. If they never 2058 * appeared, crawl back and revive the system version. 2059 */ 2060 for (int i = 0; i < expectingBetter.size(); i++) { 2061 final String packageName = expectingBetter.keyAt(i); 2062 if (!mPackages.containsKey(packageName)) { 2063 final File scanFile = expectingBetter.valueAt(i); 2064 2065 logCriticalInfo(Log.WARN, "Expected better " + packageName 2066 + " but never showed up; reverting to system"); 2067 2068 final int reparseFlags; 2069 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2070 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2071 | PackageParser.PARSE_IS_SYSTEM_DIR 2072 | PackageParser.PARSE_IS_PRIVILEGED; 2073 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2074 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2075 | PackageParser.PARSE_IS_SYSTEM_DIR; 2076 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2077 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2078 | PackageParser.PARSE_IS_SYSTEM_DIR; 2079 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2080 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2081 | PackageParser.PARSE_IS_SYSTEM_DIR; 2082 } else { 2083 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2084 continue; 2085 } 2086 2087 mSettings.enableSystemPackageLPw(packageName); 2088 2089 try { 2090 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null); 2091 } catch (PackageManagerException e) { 2092 Slog.e(TAG, "Failed to parse original system package: " 2093 + e.getMessage()); 2094 } 2095 } 2096 } 2097 } 2098 2099 // Now that we know all of the shared libraries, update all clients to have 2100 // the correct library paths. 2101 updateAllSharedLibrariesLPw(); 2102 2103 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2104 // NOTE: We ignore potential failures here during a system scan (like 2105 // the rest of the commands above) because there's precious little we 2106 // can do about it. A settings error is reported, though. 2107 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2108 false /* force dexopt */, false /* defer dexopt */); 2109 } 2110 2111 // Now that we know all the packages we are keeping, 2112 // read and update their last usage times. 2113 mPackageUsage.readLP(); 2114 2115 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2116 SystemClock.uptimeMillis()); 2117 Slog.i(TAG, "Time to scan packages: " 2118 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2119 + " seconds"); 2120 2121 // If the platform SDK has changed since the last time we booted, 2122 // we need to re-grant app permission to catch any new ones that 2123 // appear. This is really a hack, and means that apps can in some 2124 // cases get permissions that the user didn't initially explicitly 2125 // allow... it would be nice to have some better way to handle 2126 // this situation. 2127 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 2128 != mSdkVersion; 2129 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 2130 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 2131 + "; regranting permissions for internal storage"); 2132 mSettings.mInternalSdkPlatform = mSdkVersion; 2133 2134 // For now runtime permissions are toggled via a system property. 2135 if (!RUNTIME_PERMISSIONS_ENABLED) { 2136 // Remove the runtime permissions state if the feature 2137 // was disabled by flipping the system property. 2138 mSettings.deleteRuntimePermissionsFiles(); 2139 } 2140 2141 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 2142 | (regrantPermissions 2143 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 2144 : 0)); 2145 2146 // If this is the first boot, and it is a normal boot, then 2147 // we need to initialize the default preferred apps. 2148 if (!mRestoredSettings && !onlyCore) { 2149 mSettings.readDefaultPreferredAppsLPw(this, 0); 2150 } 2151 2152 // If this is first boot after an OTA, and a normal boot, then 2153 // we need to clear code cache directories. 2154 mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint); 2155 if (mIsUpgrade && !onlyCore) { 2156 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2157 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2158 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2159 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2160 } 2161 mSettings.mFingerprint = Build.FINGERPRINT; 2162 } 2163 2164 primeDomainVerificationsLPw(false); 2165 checkDefaultBrowser(); 2166 2167 // All the changes are done during package scanning. 2168 mSettings.updateInternalDatabaseVersion(); 2169 2170 // can downgrade to reader 2171 mSettings.writeLPr(); 2172 2173 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2174 SystemClock.uptimeMillis()); 2175 2176 mRequiredVerifierPackage = getRequiredVerifierLPr(); 2177 2178 mInstallerService = new PackageInstallerService(context, this); 2179 2180 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2181 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2182 mIntentFilterVerifierComponent); 2183 2184 } // synchronized (mPackages) 2185 } // synchronized (mInstallLock) 2186 2187 // Now after opening every single application zip, make sure they 2188 // are all flushed. Not really needed, but keeps things nice and 2189 // tidy. 2190 Runtime.getRuntime().gc(); 2191 } 2192 2193 @Override 2194 public boolean isFirstBoot() { 2195 return !mRestoredSettings; 2196 } 2197 2198 @Override 2199 public boolean isOnlyCoreApps() { 2200 return mOnlyCore; 2201 } 2202 2203 @Override 2204 public boolean isUpgrade() { 2205 return mIsUpgrade; 2206 } 2207 2208 private String getRequiredVerifierLPr() { 2209 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2210 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2211 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 2212 2213 String requiredVerifier = null; 2214 2215 final int N = receivers.size(); 2216 for (int i = 0; i < N; i++) { 2217 final ResolveInfo info = receivers.get(i); 2218 2219 if (info.activityInfo == null) { 2220 continue; 2221 } 2222 2223 final String packageName = info.activityInfo.packageName; 2224 2225 if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 2226 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2227 continue; 2228 } 2229 2230 if (requiredVerifier != null) { 2231 throw new RuntimeException("There can be only one required verifier"); 2232 } 2233 2234 requiredVerifier = packageName; 2235 } 2236 2237 return requiredVerifier; 2238 } 2239 2240 private ComponentName getIntentFilterVerifierComponentNameLPr() { 2241 final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2242 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2243 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */); 2244 2245 ComponentName verifierComponentName = null; 2246 2247 int priority = -1000; 2248 final int N = receivers.size(); 2249 for (int i = 0; i < N; i++) { 2250 final ResolveInfo info = receivers.get(i); 2251 2252 if (info.activityInfo == null) { 2253 continue; 2254 } 2255 2256 final String packageName = info.activityInfo.packageName; 2257 2258 final PackageSetting ps = mSettings.mPackages.get(packageName); 2259 if (ps == null) { 2260 continue; 2261 } 2262 2263 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2264 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2265 continue; 2266 } 2267 2268 // Select the IntentFilterVerifier with the highest priority 2269 if (priority < info.priority) { 2270 priority = info.priority; 2271 verifierComponentName = new ComponentName(packageName, info.activityInfo.name); 2272 Slog.d(TAG, "Selecting IntentFilterVerifier: " + verifierComponentName + 2273 " with priority: " + info.priority); 2274 } 2275 } 2276 2277 return verifierComponentName; 2278 } 2279 2280 private void primeDomainVerificationsLPw(boolean logging) { 2281 Slog.d(TAG, "Start priming domain verifications"); 2282 boolean updated = false; 2283 ArraySet<String> allHostsSet = new ArraySet<>(); 2284 for (PackageParser.Package pkg : mPackages.values()) { 2285 final String packageName = pkg.packageName; 2286 if (!hasDomainURLs(pkg)) { 2287 if (logging) { 2288 Slog.d(TAG, "No priming domain verifications for " + 2289 "package with no domain URLs: " + packageName); 2290 } 2291 continue; 2292 } 2293 if (!pkg.isSystemApp()) { 2294 if (logging) { 2295 Slog.d(TAG, "No priming domain verifications for a non system package : " + 2296 packageName); 2297 } 2298 continue; 2299 } 2300 for (PackageParser.Activity a : pkg.activities) { 2301 for (ActivityIntentInfo filter : a.intents) { 2302 if (hasValidDomains(filter, false)) { 2303 allHostsSet.addAll(filter.getHostsList()); 2304 } 2305 } 2306 } 2307 if (allHostsSet.size() == 0) { 2308 allHostsSet.add("*"); 2309 } 2310 ArrayList<String> allHostsList = new ArrayList<>(allHostsSet); 2311 IntentFilterVerificationInfo ivi = 2312 mSettings.createIntentFilterVerificationIfNeededLPw(packageName, allHostsList); 2313 if (ivi != null) { 2314 // We will always log this 2315 Slog.d(TAG, "Priming domain verifications for package: " + packageName + 2316 " with hosts:" + ivi.getDomainsString()); 2317 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 2318 updated = true; 2319 } 2320 else { 2321 if (logging) { 2322 Slog.d(TAG, "No priming domain verifications for package: " + packageName); 2323 } 2324 } 2325 allHostsSet.clear(); 2326 } 2327 if (updated) { 2328 if (logging) { 2329 Slog.d(TAG, "Will need to write primed domain verifications"); 2330 } 2331 } 2332 Slog.d(TAG, "End priming domain verifications"); 2333 } 2334 2335 private void checkDefaultBrowser() { 2336 final int myUserId = UserHandle.myUserId(); 2337 final String packageName = getDefaultBrowserPackageName(myUserId); 2338 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2339 if (info == null) { 2340 Slog.w(TAG, "Clearing default Browser as its package is no more installed: " + 2341 packageName); 2342 setDefaultBrowserPackageName(null, myUserId); 2343 } 2344 } 2345 2346 @Override 2347 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2348 throws RemoteException { 2349 try { 2350 return super.onTransact(code, data, reply, flags); 2351 } catch (RuntimeException e) { 2352 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2353 Slog.wtf(TAG, "Package Manager Crash", e); 2354 } 2355 throw e; 2356 } 2357 } 2358 2359 void cleanupInstallFailedPackage(PackageSetting ps) { 2360 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2361 2362 removeDataDirsLI(ps.volumeUuid, ps.name); 2363 if (ps.codePath != null) { 2364 if (ps.codePath.isDirectory()) { 2365 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath()); 2366 } else { 2367 ps.codePath.delete(); 2368 } 2369 } 2370 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2371 if (ps.resourcePath.isDirectory()) { 2372 FileUtils.deleteContents(ps.resourcePath); 2373 } 2374 ps.resourcePath.delete(); 2375 } 2376 mSettings.removePackageLPw(ps.name); 2377 } 2378 2379 static int[] appendInts(int[] cur, int[] add) { 2380 if (add == null) return cur; 2381 if (cur == null) return add; 2382 final int N = add.length; 2383 for (int i=0; i<N; i++) { 2384 cur = appendInt(cur, add[i]); 2385 } 2386 return cur; 2387 } 2388 2389 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2390 if (!sUserManager.exists(userId)) return null; 2391 final PackageSetting ps = (PackageSetting) p.mExtras; 2392 if (ps == null) { 2393 return null; 2394 } 2395 2396 final PermissionsState permissionsState = ps.getPermissionsState(); 2397 2398 final int[] gids = permissionsState.computeGids(userId); 2399 final Set<String> permissions = permissionsState.getPermissions(userId); 2400 final PackageUserState state = ps.readUserState(userId); 2401 2402 return PackageParser.generatePackageInfo(p, gids, flags, 2403 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2404 } 2405 2406 @Override 2407 public boolean isPackageFrozen(String packageName) { 2408 synchronized (mPackages) { 2409 final PackageSetting ps = mSettings.mPackages.get(packageName); 2410 if (ps != null) { 2411 return ps.frozen; 2412 } 2413 } 2414 Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen"); 2415 return true; 2416 } 2417 2418 @Override 2419 public boolean isPackageAvailable(String packageName, int userId) { 2420 if (!sUserManager.exists(userId)) return false; 2421 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 2422 synchronized (mPackages) { 2423 PackageParser.Package p = mPackages.get(packageName); 2424 if (p != null) { 2425 final PackageSetting ps = (PackageSetting) p.mExtras; 2426 if (ps != null) { 2427 final PackageUserState state = ps.readUserState(userId); 2428 if (state != null) { 2429 return PackageParser.isAvailable(state); 2430 } 2431 } 2432 } 2433 } 2434 return false; 2435 } 2436 2437 @Override 2438 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2439 if (!sUserManager.exists(userId)) return null; 2440 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 2441 // reader 2442 synchronized (mPackages) { 2443 PackageParser.Package p = mPackages.get(packageName); 2444 if (DEBUG_PACKAGE_INFO) 2445 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2446 if (p != null) { 2447 return generatePackageInfo(p, flags, userId); 2448 } 2449 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2450 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2451 } 2452 } 2453 return null; 2454 } 2455 2456 @Override 2457 public String[] currentToCanonicalPackageNames(String[] names) { 2458 String[] out = new String[names.length]; 2459 // reader 2460 synchronized (mPackages) { 2461 for (int i=names.length-1; i>=0; i--) { 2462 PackageSetting ps = mSettings.mPackages.get(names[i]); 2463 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2464 } 2465 } 2466 return out; 2467 } 2468 2469 @Override 2470 public String[] canonicalToCurrentPackageNames(String[] names) { 2471 String[] out = new String[names.length]; 2472 // reader 2473 synchronized (mPackages) { 2474 for (int i=names.length-1; i>=0; i--) { 2475 String cur = mSettings.mRenamedPackages.get(names[i]); 2476 out[i] = cur != null ? cur : names[i]; 2477 } 2478 } 2479 return out; 2480 } 2481 2482 @Override 2483 public int getPackageUid(String packageName, int userId) { 2484 if (!sUserManager.exists(userId)) return -1; 2485 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 2486 2487 // reader 2488 synchronized (mPackages) { 2489 PackageParser.Package p = mPackages.get(packageName); 2490 if(p != null) { 2491 return UserHandle.getUid(userId, p.applicationInfo.uid); 2492 } 2493 PackageSetting ps = mSettings.mPackages.get(packageName); 2494 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 2495 return -1; 2496 } 2497 p = ps.pkg; 2498 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 2499 } 2500 } 2501 2502 @Override 2503 public int[] getPackageGids(String packageName, int userId) throws RemoteException { 2504 if (!sUserManager.exists(userId)) { 2505 return null; 2506 } 2507 2508 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 2509 "getPackageGids"); 2510 2511 // reader 2512 synchronized (mPackages) { 2513 PackageParser.Package p = mPackages.get(packageName); 2514 if (DEBUG_PACKAGE_INFO) { 2515 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 2516 } 2517 if (p != null) { 2518 PackageSetting ps = (PackageSetting) p.mExtras; 2519 return ps.getPermissionsState().computeGids(userId); 2520 } 2521 } 2522 2523 return null; 2524 } 2525 2526 static PermissionInfo generatePermissionInfo( 2527 BasePermission bp, int flags) { 2528 if (bp.perm != null) { 2529 return PackageParser.generatePermissionInfo(bp.perm, flags); 2530 } 2531 PermissionInfo pi = new PermissionInfo(); 2532 pi.name = bp.name; 2533 pi.packageName = bp.sourcePackage; 2534 pi.nonLocalizedLabel = bp.name; 2535 pi.protectionLevel = bp.protectionLevel; 2536 return pi; 2537 } 2538 2539 @Override 2540 public PermissionInfo getPermissionInfo(String name, int flags) { 2541 // reader 2542 synchronized (mPackages) { 2543 final BasePermission p = mSettings.mPermissions.get(name); 2544 if (p != null) { 2545 return generatePermissionInfo(p, flags); 2546 } 2547 return null; 2548 } 2549 } 2550 2551 @Override 2552 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2553 // reader 2554 synchronized (mPackages) { 2555 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2556 for (BasePermission p : mSettings.mPermissions.values()) { 2557 if (group == null) { 2558 if (p.perm == null || p.perm.info.group == null) { 2559 out.add(generatePermissionInfo(p, flags)); 2560 } 2561 } else { 2562 if (p.perm != null && group.equals(p.perm.info.group)) { 2563 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2564 } 2565 } 2566 } 2567 2568 if (out.size() > 0) { 2569 return out; 2570 } 2571 return mPermissionGroups.containsKey(group) ? out : null; 2572 } 2573 } 2574 2575 @Override 2576 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2577 // reader 2578 synchronized (mPackages) { 2579 return PackageParser.generatePermissionGroupInfo( 2580 mPermissionGroups.get(name), flags); 2581 } 2582 } 2583 2584 @Override 2585 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2586 // reader 2587 synchronized (mPackages) { 2588 final int N = mPermissionGroups.size(); 2589 ArrayList<PermissionGroupInfo> out 2590 = new ArrayList<PermissionGroupInfo>(N); 2591 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2592 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2593 } 2594 return out; 2595 } 2596 } 2597 2598 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2599 int userId) { 2600 if (!sUserManager.exists(userId)) return null; 2601 PackageSetting ps = mSettings.mPackages.get(packageName); 2602 if (ps != null) { 2603 if (ps.pkg == null) { 2604 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2605 flags, userId); 2606 if (pInfo != null) { 2607 return pInfo.applicationInfo; 2608 } 2609 return null; 2610 } 2611 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2612 ps.readUserState(userId), userId); 2613 } 2614 return null; 2615 } 2616 2617 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2618 int userId) { 2619 if (!sUserManager.exists(userId)) return null; 2620 PackageSetting ps = mSettings.mPackages.get(packageName); 2621 if (ps != null) { 2622 PackageParser.Package pkg = ps.pkg; 2623 if (pkg == null) { 2624 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2625 return null; 2626 } 2627 // Only data remains, so we aren't worried about code paths 2628 pkg = new PackageParser.Package(packageName); 2629 pkg.applicationInfo.packageName = packageName; 2630 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2631 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 2632 pkg.applicationInfo.dataDir = PackageManager.getDataDirForUser(ps.volumeUuid, 2633 packageName, userId).getAbsolutePath(); 2634 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2635 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2636 } 2637 return generatePackageInfo(pkg, flags, userId); 2638 } 2639 return null; 2640 } 2641 2642 @Override 2643 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2644 if (!sUserManager.exists(userId)) return null; 2645 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2646 // writer 2647 synchronized (mPackages) { 2648 PackageParser.Package p = mPackages.get(packageName); 2649 if (DEBUG_PACKAGE_INFO) Log.v( 2650 TAG, "getApplicationInfo " + packageName 2651 + ": " + p); 2652 if (p != null) { 2653 PackageSetting ps = mSettings.mPackages.get(packageName); 2654 if (ps == null) return null; 2655 // Note: isEnabledLP() does not apply here - always return info 2656 return PackageParser.generateApplicationInfo( 2657 p, flags, ps.readUserState(userId), userId); 2658 } 2659 if ("android".equals(packageName)||"system".equals(packageName)) { 2660 return mAndroidApplication; 2661 } 2662 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2663 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2664 } 2665 } 2666 return null; 2667 } 2668 2669 @Override 2670 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 2671 final IPackageDataObserver observer) { 2672 mContext.enforceCallingOrSelfPermission( 2673 android.Manifest.permission.CLEAR_APP_CACHE, null); 2674 // Queue up an async operation since clearing cache may take a little while. 2675 mHandler.post(new Runnable() { 2676 public void run() { 2677 mHandler.removeCallbacks(this); 2678 int retCode = -1; 2679 synchronized (mInstallLock) { 2680 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2681 if (retCode < 0) { 2682 Slog.w(TAG, "Couldn't clear application caches"); 2683 } 2684 } 2685 if (observer != null) { 2686 try { 2687 observer.onRemoveCompleted(null, (retCode >= 0)); 2688 } catch (RemoteException e) { 2689 Slog.w(TAG, "RemoveException when invoking call back"); 2690 } 2691 } 2692 } 2693 }); 2694 } 2695 2696 @Override 2697 public void freeStorage(final String volumeUuid, final long freeStorageSize, 2698 final IntentSender pi) { 2699 mContext.enforceCallingOrSelfPermission( 2700 android.Manifest.permission.CLEAR_APP_CACHE, null); 2701 // Queue up an async operation since clearing cache may take a little while. 2702 mHandler.post(new Runnable() { 2703 public void run() { 2704 mHandler.removeCallbacks(this); 2705 int retCode = -1; 2706 synchronized (mInstallLock) { 2707 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2708 if (retCode < 0) { 2709 Slog.w(TAG, "Couldn't clear application caches"); 2710 } 2711 } 2712 if(pi != null) { 2713 try { 2714 // Callback via pending intent 2715 int code = (retCode >= 0) ? 1 : 0; 2716 pi.sendIntent(null, code, null, 2717 null, null); 2718 } catch (SendIntentException e1) { 2719 Slog.i(TAG, "Failed to send pending intent"); 2720 } 2721 } 2722 } 2723 }); 2724 } 2725 2726 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 2727 synchronized (mInstallLock) { 2728 if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) { 2729 throw new IOException("Failed to free enough space"); 2730 } 2731 } 2732 } 2733 2734 @Override 2735 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2736 if (!sUserManager.exists(userId)) return null; 2737 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 2738 synchronized (mPackages) { 2739 PackageParser.Activity a = mActivities.mActivities.get(component); 2740 2741 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2742 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2743 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2744 if (ps == null) return null; 2745 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2746 userId); 2747 } 2748 if (mResolveComponentName.equals(component)) { 2749 return PackageParser.generateActivityInfo(mResolveActivity, flags, 2750 new PackageUserState(), userId); 2751 } 2752 } 2753 return null; 2754 } 2755 2756 @Override 2757 public boolean activitySupportsIntent(ComponentName component, Intent intent, 2758 String resolvedType) { 2759 synchronized (mPackages) { 2760 PackageParser.Activity a = mActivities.mActivities.get(component); 2761 if (a == null) { 2762 return false; 2763 } 2764 for (int i=0; i<a.intents.size(); i++) { 2765 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 2766 intent.getData(), intent.getCategories(), TAG) >= 0) { 2767 return true; 2768 } 2769 } 2770 return false; 2771 } 2772 } 2773 2774 @Override 2775 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2776 if (!sUserManager.exists(userId)) return null; 2777 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 2778 synchronized (mPackages) { 2779 PackageParser.Activity a = mReceivers.mActivities.get(component); 2780 if (DEBUG_PACKAGE_INFO) Log.v( 2781 TAG, "getReceiverInfo " + component + ": " + a); 2782 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2783 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2784 if (ps == null) return null; 2785 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2786 userId); 2787 } 2788 } 2789 return null; 2790 } 2791 2792 @Override 2793 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2794 if (!sUserManager.exists(userId)) return null; 2795 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 2796 synchronized (mPackages) { 2797 PackageParser.Service s = mServices.mServices.get(component); 2798 if (DEBUG_PACKAGE_INFO) Log.v( 2799 TAG, "getServiceInfo " + component + ": " + s); 2800 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2801 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2802 if (ps == null) return null; 2803 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2804 userId); 2805 } 2806 } 2807 return null; 2808 } 2809 2810 @Override 2811 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2812 if (!sUserManager.exists(userId)) return null; 2813 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 2814 synchronized (mPackages) { 2815 PackageParser.Provider p = mProviders.mProviders.get(component); 2816 if (DEBUG_PACKAGE_INFO) Log.v( 2817 TAG, "getProviderInfo " + component + ": " + p); 2818 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2819 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2820 if (ps == null) return null; 2821 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2822 userId); 2823 } 2824 } 2825 return null; 2826 } 2827 2828 @Override 2829 public String[] getSystemSharedLibraryNames() { 2830 Set<String> libSet; 2831 synchronized (mPackages) { 2832 libSet = mSharedLibraries.keySet(); 2833 int size = libSet.size(); 2834 if (size > 0) { 2835 String[] libs = new String[size]; 2836 libSet.toArray(libs); 2837 return libs; 2838 } 2839 } 2840 return null; 2841 } 2842 2843 /** 2844 * @hide 2845 */ 2846 PackageParser.Package findSharedNonSystemLibrary(String libName) { 2847 synchronized (mPackages) { 2848 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 2849 if (lib != null && lib.apk != null) { 2850 return mPackages.get(lib.apk); 2851 } 2852 } 2853 return null; 2854 } 2855 2856 @Override 2857 public FeatureInfo[] getSystemAvailableFeatures() { 2858 Collection<FeatureInfo> featSet; 2859 synchronized (mPackages) { 2860 featSet = mAvailableFeatures.values(); 2861 int size = featSet.size(); 2862 if (size > 0) { 2863 FeatureInfo[] features = new FeatureInfo[size+1]; 2864 featSet.toArray(features); 2865 FeatureInfo fi = new FeatureInfo(); 2866 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2867 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2868 features[size] = fi; 2869 return features; 2870 } 2871 } 2872 return null; 2873 } 2874 2875 @Override 2876 public boolean hasSystemFeature(String name) { 2877 synchronized (mPackages) { 2878 return mAvailableFeatures.containsKey(name); 2879 } 2880 } 2881 2882 private void checkValidCaller(int uid, int userId) { 2883 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2884 return; 2885 2886 throw new SecurityException("Caller uid=" + uid 2887 + " is not privileged to communicate with user=" + userId); 2888 } 2889 2890 @Override 2891 public int checkPermission(String permName, String pkgName, int userId) { 2892 if (!sUserManager.exists(userId)) { 2893 return PackageManager.PERMISSION_DENIED; 2894 } 2895 2896 synchronized (mPackages) { 2897 final PackageParser.Package p = mPackages.get(pkgName); 2898 if (p != null && p.mExtras != null) { 2899 final PackageSetting ps = (PackageSetting) p.mExtras; 2900 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2901 return PackageManager.PERMISSION_GRANTED; 2902 } 2903 } 2904 } 2905 2906 return PackageManager.PERMISSION_DENIED; 2907 } 2908 2909 @Override 2910 public int checkUidPermission(String permName, int uid) { 2911 final int userId = UserHandle.getUserId(uid); 2912 2913 if (!sUserManager.exists(userId)) { 2914 return PackageManager.PERMISSION_DENIED; 2915 } 2916 2917 synchronized (mPackages) { 2918 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2919 if (obj != null) { 2920 final SettingBase ps = (SettingBase) obj; 2921 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2922 return PackageManager.PERMISSION_GRANTED; 2923 } 2924 } else { 2925 ArraySet<String> perms = mSystemPermissions.get(uid); 2926 if (perms != null && perms.contains(permName)) { 2927 return PackageManager.PERMISSION_GRANTED; 2928 } 2929 } 2930 } 2931 2932 return PackageManager.PERMISSION_DENIED; 2933 } 2934 2935 /** 2936 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2937 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2938 * @param checkShell TODO(yamasani): 2939 * @param message the message to log on security exception 2940 */ 2941 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 2942 boolean checkShell, String message) { 2943 if (userId < 0) { 2944 throw new IllegalArgumentException("Invalid userId " + userId); 2945 } 2946 if (checkShell) { 2947 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 2948 } 2949 if (userId == UserHandle.getUserId(callingUid)) return; 2950 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2951 if (requireFullPermission) { 2952 mContext.enforceCallingOrSelfPermission( 2953 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2954 } else { 2955 try { 2956 mContext.enforceCallingOrSelfPermission( 2957 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2958 } catch (SecurityException se) { 2959 mContext.enforceCallingOrSelfPermission( 2960 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2961 } 2962 } 2963 } 2964 } 2965 2966 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 2967 if (callingUid == Process.SHELL_UID) { 2968 if (userHandle >= 0 2969 && sUserManager.hasUserRestriction(restriction, userHandle)) { 2970 throw new SecurityException("Shell does not have permission to access user " 2971 + userHandle); 2972 } else if (userHandle < 0) { 2973 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 2974 + Debug.getCallers(3)); 2975 } 2976 } 2977 } 2978 2979 private BasePermission findPermissionTreeLP(String permName) { 2980 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2981 if (permName.startsWith(bp.name) && 2982 permName.length() > bp.name.length() && 2983 permName.charAt(bp.name.length()) == '.') { 2984 return bp; 2985 } 2986 } 2987 return null; 2988 } 2989 2990 private BasePermission checkPermissionTreeLP(String permName) { 2991 if (permName != null) { 2992 BasePermission bp = findPermissionTreeLP(permName); 2993 if (bp != null) { 2994 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2995 return bp; 2996 } 2997 throw new SecurityException("Calling uid " 2998 + Binder.getCallingUid() 2999 + " is not allowed to add to permission tree " 3000 + bp.name + " owned by uid " + bp.uid); 3001 } 3002 } 3003 throw new SecurityException("No permission tree found for " + permName); 3004 } 3005 3006 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3007 if (s1 == null) { 3008 return s2 == null; 3009 } 3010 if (s2 == null) { 3011 return false; 3012 } 3013 if (s1.getClass() != s2.getClass()) { 3014 return false; 3015 } 3016 return s1.equals(s2); 3017 } 3018 3019 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3020 if (pi1.icon != pi2.icon) return false; 3021 if (pi1.logo != pi2.logo) return false; 3022 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3023 if (!compareStrings(pi1.name, pi2.name)) return false; 3024 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3025 // We'll take care of setting this one. 3026 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3027 // These are not currently stored in settings. 3028 //if (!compareStrings(pi1.group, pi2.group)) return false; 3029 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3030 //if (pi1.labelRes != pi2.labelRes) return false; 3031 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3032 return true; 3033 } 3034 3035 int permissionInfoFootprint(PermissionInfo info) { 3036 int size = info.name.length(); 3037 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3038 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3039 return size; 3040 } 3041 3042 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3043 int size = 0; 3044 for (BasePermission perm : mSettings.mPermissions.values()) { 3045 if (perm.uid == tree.uid) { 3046 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3047 } 3048 } 3049 return size; 3050 } 3051 3052 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3053 // We calculate the max size of permissions defined by this uid and throw 3054 // if that plus the size of 'info' would exceed our stated maximum. 3055 if (tree.uid != Process.SYSTEM_UID) { 3056 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3057 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3058 throw new SecurityException("Permission tree size cap exceeded"); 3059 } 3060 } 3061 } 3062 3063 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3064 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3065 throw new SecurityException("Label must be specified in permission"); 3066 } 3067 BasePermission tree = checkPermissionTreeLP(info.name); 3068 BasePermission bp = mSettings.mPermissions.get(info.name); 3069 boolean added = bp == null; 3070 boolean changed = true; 3071 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3072 if (added) { 3073 enforcePermissionCapLocked(info, tree); 3074 bp = new BasePermission(info.name, tree.sourcePackage, 3075 BasePermission.TYPE_DYNAMIC); 3076 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3077 throw new SecurityException( 3078 "Not allowed to modify non-dynamic permission " 3079 + info.name); 3080 } else { 3081 if (bp.protectionLevel == fixedLevel 3082 && bp.perm.owner.equals(tree.perm.owner) 3083 && bp.uid == tree.uid 3084 && comparePermissionInfos(bp.perm.info, info)) { 3085 changed = false; 3086 } 3087 } 3088 bp.protectionLevel = fixedLevel; 3089 info = new PermissionInfo(info); 3090 info.protectionLevel = fixedLevel; 3091 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3092 bp.perm.info.packageName = tree.perm.info.packageName; 3093 bp.uid = tree.uid; 3094 if (added) { 3095 mSettings.mPermissions.put(info.name, bp); 3096 } 3097 if (changed) { 3098 if (!async) { 3099 mSettings.writeLPr(); 3100 } else { 3101 scheduleWriteSettingsLocked(); 3102 } 3103 } 3104 return added; 3105 } 3106 3107 @Override 3108 public boolean addPermission(PermissionInfo info) { 3109 synchronized (mPackages) { 3110 return addPermissionLocked(info, false); 3111 } 3112 } 3113 3114 @Override 3115 public boolean addPermissionAsync(PermissionInfo info) { 3116 synchronized (mPackages) { 3117 return addPermissionLocked(info, true); 3118 } 3119 } 3120 3121 @Override 3122 public void removePermission(String name) { 3123 synchronized (mPackages) { 3124 checkPermissionTreeLP(name); 3125 BasePermission bp = mSettings.mPermissions.get(name); 3126 if (bp != null) { 3127 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3128 throw new SecurityException( 3129 "Not allowed to modify non-dynamic permission " 3130 + name); 3131 } 3132 mSettings.mPermissions.remove(name); 3133 mSettings.writeLPr(); 3134 } 3135 } 3136 } 3137 3138 private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg, 3139 BasePermission bp) { 3140 int index = pkg.requestedPermissions.indexOf(bp.name); 3141 if (index == -1) { 3142 throw new SecurityException("Package " + pkg.packageName 3143 + " has not requested permission " + bp.name); 3144 } 3145 if (!bp.isRuntime()) { 3146 throw new SecurityException("Permission " + bp.name 3147 + " is not a changeable permission type"); 3148 } 3149 } 3150 3151 @Override 3152 public boolean grantPermission(String packageName, String name, int userId) { 3153 if (!RUNTIME_PERMISSIONS_ENABLED) { 3154 return false; 3155 } 3156 3157 if (!sUserManager.exists(userId)) { 3158 return false; 3159 } 3160 3161 mContext.enforceCallingOrSelfPermission( 3162 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3163 "grantPermission"); 3164 3165 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3166 "grantPermission"); 3167 3168 boolean gidsChanged = false; 3169 final SettingBase sb; 3170 3171 synchronized (mPackages) { 3172 final PackageParser.Package pkg = mPackages.get(packageName); 3173 if (pkg == null) { 3174 throw new IllegalArgumentException("Unknown package: " + packageName); 3175 } 3176 3177 final BasePermission bp = mSettings.mPermissions.get(name); 3178 if (bp == null) { 3179 throw new IllegalArgumentException("Unknown permission: " + name); 3180 } 3181 3182 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3183 3184 sb = (SettingBase) pkg.mExtras; 3185 if (sb == null) { 3186 throw new IllegalArgumentException("Unknown package: " + packageName); 3187 } 3188 3189 final PermissionsState permissionsState = sb.getPermissionsState(); 3190 3191 final int result = permissionsState.grantRuntimePermission(bp, userId); 3192 switch (result) { 3193 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3194 return false; 3195 } 3196 3197 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3198 gidsChanged = true; 3199 } break; 3200 } 3201 3202 // Not critical if that is lost - app has to request again. 3203 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3204 } 3205 3206 if (gidsChanged) { 3207 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED); 3208 } 3209 3210 return true; 3211 } 3212 3213 @Override 3214 public boolean revokePermission(String packageName, String name, int userId) { 3215 if (!RUNTIME_PERMISSIONS_ENABLED) { 3216 return false; 3217 } 3218 3219 if (!sUserManager.exists(userId)) { 3220 return false; 3221 } 3222 3223 mContext.enforceCallingOrSelfPermission( 3224 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3225 "revokePermission"); 3226 3227 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3228 "revokePermission"); 3229 3230 final SettingBase sb; 3231 3232 synchronized (mPackages) { 3233 final PackageParser.Package pkg = mPackages.get(packageName); 3234 if (pkg == null) { 3235 throw new IllegalArgumentException("Unknown package: " + packageName); 3236 } 3237 3238 final BasePermission bp = mSettings.mPermissions.get(name); 3239 if (bp == null) { 3240 throw new IllegalArgumentException("Unknown permission: " + name); 3241 } 3242 3243 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3244 3245 sb = (SettingBase) pkg.mExtras; 3246 if (sb == null) { 3247 throw new IllegalArgumentException("Unknown package: " + packageName); 3248 } 3249 3250 final PermissionsState permissionsState = sb.getPermissionsState(); 3251 3252 if (permissionsState.revokeRuntimePermission(bp, userId) == 3253 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3254 return false; 3255 } 3256 3257 // Critical, after this call all should never have the permission. 3258 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3259 } 3260 3261 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 3262 3263 return true; 3264 } 3265 3266 @Override 3267 public boolean isProtectedBroadcast(String actionName) { 3268 synchronized (mPackages) { 3269 return mProtectedBroadcasts.contains(actionName); 3270 } 3271 } 3272 3273 @Override 3274 public int checkSignatures(String pkg1, String pkg2) { 3275 synchronized (mPackages) { 3276 final PackageParser.Package p1 = mPackages.get(pkg1); 3277 final PackageParser.Package p2 = mPackages.get(pkg2); 3278 if (p1 == null || p1.mExtras == null 3279 || p2 == null || p2.mExtras == null) { 3280 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3281 } 3282 return compareSignatures(p1.mSignatures, p2.mSignatures); 3283 } 3284 } 3285 3286 @Override 3287 public int checkUidSignatures(int uid1, int uid2) { 3288 // Map to base uids. 3289 uid1 = UserHandle.getAppId(uid1); 3290 uid2 = UserHandle.getAppId(uid2); 3291 // reader 3292 synchronized (mPackages) { 3293 Signature[] s1; 3294 Signature[] s2; 3295 Object obj = mSettings.getUserIdLPr(uid1); 3296 if (obj != null) { 3297 if (obj instanceof SharedUserSetting) { 3298 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 3299 } else if (obj instanceof PackageSetting) { 3300 s1 = ((PackageSetting)obj).signatures.mSignatures; 3301 } else { 3302 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3303 } 3304 } else { 3305 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3306 } 3307 obj = mSettings.getUserIdLPr(uid2); 3308 if (obj != null) { 3309 if (obj instanceof SharedUserSetting) { 3310 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 3311 } else if (obj instanceof PackageSetting) { 3312 s2 = ((PackageSetting)obj).signatures.mSignatures; 3313 } else { 3314 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3315 } 3316 } else { 3317 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3318 } 3319 return compareSignatures(s1, s2); 3320 } 3321 } 3322 3323 private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) { 3324 final long identity = Binder.clearCallingIdentity(); 3325 try { 3326 if (sb instanceof SharedUserSetting) { 3327 SharedUserSetting sus = (SharedUserSetting) sb; 3328 final int packageCount = sus.packages.size(); 3329 for (int i = 0; i < packageCount; i++) { 3330 PackageSetting susPs = sus.packages.valueAt(i); 3331 if (userId == UserHandle.USER_ALL) { 3332 killApplication(susPs.pkg.packageName, susPs.appId, reason); 3333 } else { 3334 final int uid = UserHandle.getUid(userId, susPs.appId); 3335 killUid(uid, reason); 3336 } 3337 } 3338 } else if (sb instanceof PackageSetting) { 3339 PackageSetting ps = (PackageSetting) sb; 3340 if (userId == UserHandle.USER_ALL) { 3341 killApplication(ps.pkg.packageName, ps.appId, reason); 3342 } else { 3343 final int uid = UserHandle.getUid(userId, ps.appId); 3344 killUid(uid, reason); 3345 } 3346 } 3347 } finally { 3348 Binder.restoreCallingIdentity(identity); 3349 } 3350 } 3351 3352 private static void killUid(int uid, String reason) { 3353 IActivityManager am = ActivityManagerNative.getDefault(); 3354 if (am != null) { 3355 try { 3356 am.killUid(uid, reason); 3357 } catch (RemoteException e) { 3358 /* ignore - same process */ 3359 } 3360 } 3361 } 3362 3363 /** 3364 * Compares two sets of signatures. Returns: 3365 * <br /> 3366 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 3367 * <br /> 3368 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 3369 * <br /> 3370 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 3371 * <br /> 3372 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 3373 * <br /> 3374 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 3375 */ 3376 static int compareSignatures(Signature[] s1, Signature[] s2) { 3377 if (s1 == null) { 3378 return s2 == null 3379 ? PackageManager.SIGNATURE_NEITHER_SIGNED 3380 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 3381 } 3382 3383 if (s2 == null) { 3384 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 3385 } 3386 3387 if (s1.length != s2.length) { 3388 return PackageManager.SIGNATURE_NO_MATCH; 3389 } 3390 3391 // Since both signature sets are of size 1, we can compare without HashSets. 3392 if (s1.length == 1) { 3393 return s1[0].equals(s2[0]) ? 3394 PackageManager.SIGNATURE_MATCH : 3395 PackageManager.SIGNATURE_NO_MATCH; 3396 } 3397 3398 ArraySet<Signature> set1 = new ArraySet<Signature>(); 3399 for (Signature sig : s1) { 3400 set1.add(sig); 3401 } 3402 ArraySet<Signature> set2 = new ArraySet<Signature>(); 3403 for (Signature sig : s2) { 3404 set2.add(sig); 3405 } 3406 // Make sure s2 contains all signatures in s1. 3407 if (set1.equals(set2)) { 3408 return PackageManager.SIGNATURE_MATCH; 3409 } 3410 return PackageManager.SIGNATURE_NO_MATCH; 3411 } 3412 3413 /** 3414 * If the database version for this type of package (internal storage or 3415 * external storage) is less than the version where package signatures 3416 * were updated, return true. 3417 */ 3418 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3419 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan( 3420 DatabaseVersion.SIGNATURE_END_ENTITY)) 3421 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan( 3422 DatabaseVersion.SIGNATURE_END_ENTITY)); 3423 } 3424 3425 /** 3426 * Used for backward compatibility to make sure any packages with 3427 * certificate chains get upgraded to the new style. {@code existingSigs} 3428 * will be in the old format (since they were stored on disk from before the 3429 * system upgrade) and {@code scannedSigs} will be in the newer format. 3430 */ 3431 private int compareSignaturesCompat(PackageSignatures existingSigs, 3432 PackageParser.Package scannedPkg) { 3433 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 3434 return PackageManager.SIGNATURE_NO_MATCH; 3435 } 3436 3437 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 3438 for (Signature sig : existingSigs.mSignatures) { 3439 existingSet.add(sig); 3440 } 3441 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 3442 for (Signature sig : scannedPkg.mSignatures) { 3443 try { 3444 Signature[] chainSignatures = sig.getChainSignatures(); 3445 for (Signature chainSig : chainSignatures) { 3446 scannedCompatSet.add(chainSig); 3447 } 3448 } catch (CertificateEncodingException e) { 3449 scannedCompatSet.add(sig); 3450 } 3451 } 3452 /* 3453 * Make sure the expanded scanned set contains all signatures in the 3454 * existing one. 3455 */ 3456 if (scannedCompatSet.equals(existingSet)) { 3457 // Migrate the old signatures to the new scheme. 3458 existingSigs.assignSignatures(scannedPkg.mSignatures); 3459 // The new KeySets will be re-added later in the scanning process. 3460 synchronized (mPackages) { 3461 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 3462 } 3463 return PackageManager.SIGNATURE_MATCH; 3464 } 3465 return PackageManager.SIGNATURE_NO_MATCH; 3466 } 3467 3468 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3469 if (isExternal(scannedPkg)) { 3470 return mSettings.isExternalDatabaseVersionOlderThan( 3471 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3472 } else { 3473 return mSettings.isInternalDatabaseVersionOlderThan( 3474 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3475 } 3476 } 3477 3478 private int compareSignaturesRecover(PackageSignatures existingSigs, 3479 PackageParser.Package scannedPkg) { 3480 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 3481 return PackageManager.SIGNATURE_NO_MATCH; 3482 } 3483 3484 String msg = null; 3485 try { 3486 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 3487 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 3488 + scannedPkg.packageName); 3489 return PackageManager.SIGNATURE_MATCH; 3490 } 3491 } catch (CertificateException e) { 3492 msg = e.getMessage(); 3493 } 3494 3495 logCriticalInfo(Log.INFO, 3496 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 3497 return PackageManager.SIGNATURE_NO_MATCH; 3498 } 3499 3500 @Override 3501 public String[] getPackagesForUid(int uid) { 3502 uid = UserHandle.getAppId(uid); 3503 // reader 3504 synchronized (mPackages) { 3505 Object obj = mSettings.getUserIdLPr(uid); 3506 if (obj instanceof SharedUserSetting) { 3507 final SharedUserSetting sus = (SharedUserSetting) obj; 3508 final int N = sus.packages.size(); 3509 final String[] res = new String[N]; 3510 final Iterator<PackageSetting> it = sus.packages.iterator(); 3511 int i = 0; 3512 while (it.hasNext()) { 3513 res[i++] = it.next().name; 3514 } 3515 return res; 3516 } else if (obj instanceof PackageSetting) { 3517 final PackageSetting ps = (PackageSetting) obj; 3518 return new String[] { ps.name }; 3519 } 3520 } 3521 return null; 3522 } 3523 3524 @Override 3525 public String getNameForUid(int uid) { 3526 // reader 3527 synchronized (mPackages) { 3528 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3529 if (obj instanceof SharedUserSetting) { 3530 final SharedUserSetting sus = (SharedUserSetting) obj; 3531 return sus.name + ":" + sus.userId; 3532 } else if (obj instanceof PackageSetting) { 3533 final PackageSetting ps = (PackageSetting) obj; 3534 return ps.name; 3535 } 3536 } 3537 return null; 3538 } 3539 3540 @Override 3541 public int getUidForSharedUser(String sharedUserName) { 3542 if(sharedUserName == null) { 3543 return -1; 3544 } 3545 // reader 3546 synchronized (mPackages) { 3547 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 3548 if (suid == null) { 3549 return -1; 3550 } 3551 return suid.userId; 3552 } 3553 } 3554 3555 @Override 3556 public int getFlagsForUid(int uid) { 3557 synchronized (mPackages) { 3558 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3559 if (obj instanceof SharedUserSetting) { 3560 final SharedUserSetting sus = (SharedUserSetting) obj; 3561 return sus.pkgFlags; 3562 } else if (obj instanceof PackageSetting) { 3563 final PackageSetting ps = (PackageSetting) obj; 3564 return ps.pkgFlags; 3565 } 3566 } 3567 return 0; 3568 } 3569 3570 @Override 3571 public int getPrivateFlagsForUid(int uid) { 3572 synchronized (mPackages) { 3573 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3574 if (obj instanceof SharedUserSetting) { 3575 final SharedUserSetting sus = (SharedUserSetting) obj; 3576 return sus.pkgPrivateFlags; 3577 } else if (obj instanceof PackageSetting) { 3578 final PackageSetting ps = (PackageSetting) obj; 3579 return ps.pkgPrivateFlags; 3580 } 3581 } 3582 return 0; 3583 } 3584 3585 @Override 3586 public boolean isUidPrivileged(int uid) { 3587 uid = UserHandle.getAppId(uid); 3588 // reader 3589 synchronized (mPackages) { 3590 Object obj = mSettings.getUserIdLPr(uid); 3591 if (obj instanceof SharedUserSetting) { 3592 final SharedUserSetting sus = (SharedUserSetting) obj; 3593 final Iterator<PackageSetting> it = sus.packages.iterator(); 3594 while (it.hasNext()) { 3595 if (it.next().isPrivileged()) { 3596 return true; 3597 } 3598 } 3599 } else if (obj instanceof PackageSetting) { 3600 final PackageSetting ps = (PackageSetting) obj; 3601 return ps.isPrivileged(); 3602 } 3603 } 3604 return false; 3605 } 3606 3607 @Override 3608 public String[] getAppOpPermissionPackages(String permissionName) { 3609 synchronized (mPackages) { 3610 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 3611 if (pkgs == null) { 3612 return null; 3613 } 3614 return pkgs.toArray(new String[pkgs.size()]); 3615 } 3616 } 3617 3618 @Override 3619 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 3620 int flags, int userId) { 3621 if (!sUserManager.exists(userId)) return null; 3622 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 3623 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3624 return chooseBestActivity(intent, resolvedType, flags, query, userId); 3625 } 3626 3627 @Override 3628 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 3629 IntentFilter filter, int match, ComponentName activity) { 3630 final int userId = UserHandle.getCallingUserId(); 3631 if (DEBUG_PREFERRED) { 3632 Log.v(TAG, "setLastChosenActivity intent=" + intent 3633 + " resolvedType=" + resolvedType 3634 + " flags=" + flags 3635 + " filter=" + filter 3636 + " match=" + match 3637 + " activity=" + activity); 3638 filter.dump(new PrintStreamPrinter(System.out), " "); 3639 } 3640 intent.setComponent(null); 3641 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3642 // Find any earlier preferred or last chosen entries and nuke them 3643 findPreferredActivity(intent, resolvedType, 3644 flags, query, 0, false, true, false, userId); 3645 // Add the new activity as the last chosen for this filter 3646 addPreferredActivityInternal(filter, match, null, activity, false, userId, 3647 "Setting last chosen"); 3648 } 3649 3650 @Override 3651 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 3652 final int userId = UserHandle.getCallingUserId(); 3653 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 3654 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3655 return findPreferredActivity(intent, resolvedType, flags, query, 0, 3656 false, false, false, userId); 3657 } 3658 3659 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 3660 int flags, List<ResolveInfo> query, int userId) { 3661 if (query != null) { 3662 final int N = query.size(); 3663 if (N == 1) { 3664 return query.get(0); 3665 } else if (N > 1) { 3666 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3667 // If there is more than one activity with the same priority, 3668 // then let the user decide between them. 3669 ResolveInfo r0 = query.get(0); 3670 ResolveInfo r1 = query.get(1); 3671 if (DEBUG_INTENT_MATCHING || debug) { 3672 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 3673 + r1.activityInfo.name + "=" + r1.priority); 3674 } 3675 // If the first activity has a higher priority, or a different 3676 // default, then it is always desireable to pick it. 3677 if (r0.priority != r1.priority 3678 || r0.preferredOrder != r1.preferredOrder 3679 || r0.isDefault != r1.isDefault) { 3680 return query.get(0); 3681 } 3682 // If we have saved a preference for a preferred activity for 3683 // this Intent, use that. 3684 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 3685 flags, query, r0.priority, true, false, debug, userId); 3686 if (ri != null) { 3687 return ri; 3688 } 3689 if (userId != 0) { 3690 ri = new ResolveInfo(mResolveInfo); 3691 ri.activityInfo = new ActivityInfo(ri.activityInfo); 3692 ri.activityInfo.applicationInfo = new ApplicationInfo( 3693 ri.activityInfo.applicationInfo); 3694 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 3695 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 3696 return ri; 3697 } 3698 return mResolveInfo; 3699 } 3700 } 3701 return null; 3702 } 3703 3704 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 3705 int flags, List<ResolveInfo> query, boolean debug, int userId) { 3706 final int N = query.size(); 3707 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 3708 .get(userId); 3709 // Get the list of persistent preferred activities that handle the intent 3710 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 3711 List<PersistentPreferredActivity> pprefs = ppir != null 3712 ? ppir.queryIntent(intent, resolvedType, 3713 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3714 : null; 3715 if (pprefs != null && pprefs.size() > 0) { 3716 final int M = pprefs.size(); 3717 for (int i=0; i<M; i++) { 3718 final PersistentPreferredActivity ppa = pprefs.get(i); 3719 if (DEBUG_PREFERRED || debug) { 3720 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 3721 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 3722 + "\n component=" + ppa.mComponent); 3723 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3724 } 3725 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 3726 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3727 if (DEBUG_PREFERRED || debug) { 3728 Slog.v(TAG, "Found persistent preferred activity:"); 3729 if (ai != null) { 3730 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3731 } else { 3732 Slog.v(TAG, " null"); 3733 } 3734 } 3735 if (ai == null) { 3736 // This previously registered persistent preferred activity 3737 // component is no longer known. Ignore it and do NOT remove it. 3738 continue; 3739 } 3740 for (int j=0; j<N; j++) { 3741 final ResolveInfo ri = query.get(j); 3742 if (!ri.activityInfo.applicationInfo.packageName 3743 .equals(ai.applicationInfo.packageName)) { 3744 continue; 3745 } 3746 if (!ri.activityInfo.name.equals(ai.name)) { 3747 continue; 3748 } 3749 // Found a persistent preference that can handle the intent. 3750 if (DEBUG_PREFERRED || debug) { 3751 Slog.v(TAG, "Returning persistent preferred activity: " + 3752 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3753 } 3754 return ri; 3755 } 3756 } 3757 } 3758 return null; 3759 } 3760 3761 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 3762 List<ResolveInfo> query, int priority, boolean always, 3763 boolean removeMatches, boolean debug, int userId) { 3764 if (!sUserManager.exists(userId)) return null; 3765 // writer 3766 synchronized (mPackages) { 3767 if (intent.getSelector() != null) { 3768 intent = intent.getSelector(); 3769 } 3770 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3771 3772 // Try to find a matching persistent preferred activity. 3773 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 3774 debug, userId); 3775 3776 // If a persistent preferred activity matched, use it. 3777 if (pri != null) { 3778 return pri; 3779 } 3780 3781 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 3782 // Get the list of preferred activities that handle the intent 3783 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 3784 List<PreferredActivity> prefs = pir != null 3785 ? pir.queryIntent(intent, resolvedType, 3786 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3787 : null; 3788 if (prefs != null && prefs.size() > 0) { 3789 boolean changed = false; 3790 try { 3791 // First figure out how good the original match set is. 3792 // We will only allow preferred activities that came 3793 // from the same match quality. 3794 int match = 0; 3795 3796 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 3797 3798 final int N = query.size(); 3799 for (int j=0; j<N; j++) { 3800 final ResolveInfo ri = query.get(j); 3801 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 3802 + ": 0x" + Integer.toHexString(match)); 3803 if (ri.match > match) { 3804 match = ri.match; 3805 } 3806 } 3807 3808 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 3809 + Integer.toHexString(match)); 3810 3811 match &= IntentFilter.MATCH_CATEGORY_MASK; 3812 final int M = prefs.size(); 3813 for (int i=0; i<M; i++) { 3814 final PreferredActivity pa = prefs.get(i); 3815 if (DEBUG_PREFERRED || debug) { 3816 Slog.v(TAG, "Checking PreferredActivity ds=" 3817 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 3818 + "\n component=" + pa.mPref.mComponent); 3819 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3820 } 3821 if (pa.mPref.mMatch != match) { 3822 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 3823 + Integer.toHexString(pa.mPref.mMatch)); 3824 continue; 3825 } 3826 // If it's not an "always" type preferred activity and that's what we're 3827 // looking for, skip it. 3828 if (always && !pa.mPref.mAlways) { 3829 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 3830 continue; 3831 } 3832 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 3833 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3834 if (DEBUG_PREFERRED || debug) { 3835 Slog.v(TAG, "Found preferred activity:"); 3836 if (ai != null) { 3837 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3838 } else { 3839 Slog.v(TAG, " null"); 3840 } 3841 } 3842 if (ai == null) { 3843 // This previously registered preferred activity 3844 // component is no longer known. Most likely an update 3845 // to the app was installed and in the new version this 3846 // component no longer exists. Clean it up by removing 3847 // it from the preferred activities list, and skip it. 3848 Slog.w(TAG, "Removing dangling preferred activity: " 3849 + pa.mPref.mComponent); 3850 pir.removeFilter(pa); 3851 changed = true; 3852 continue; 3853 } 3854 for (int j=0; j<N; j++) { 3855 final ResolveInfo ri = query.get(j); 3856 if (!ri.activityInfo.applicationInfo.packageName 3857 .equals(ai.applicationInfo.packageName)) { 3858 continue; 3859 } 3860 if (!ri.activityInfo.name.equals(ai.name)) { 3861 continue; 3862 } 3863 3864 if (removeMatches) { 3865 pir.removeFilter(pa); 3866 changed = true; 3867 if (DEBUG_PREFERRED) { 3868 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 3869 } 3870 break; 3871 } 3872 3873 // Okay we found a previously set preferred or last chosen app. 3874 // If the result set is different from when this 3875 // was created, we need to clear it and re-ask the 3876 // user their preference, if we're looking for an "always" type entry. 3877 if (always && !pa.mPref.sameSet(query)) { 3878 Slog.i(TAG, "Result set changed, dropping preferred activity for " 3879 + intent + " type " + resolvedType); 3880 if (DEBUG_PREFERRED) { 3881 Slog.v(TAG, "Removing preferred activity since set changed " 3882 + pa.mPref.mComponent); 3883 } 3884 pir.removeFilter(pa); 3885 // Re-add the filter as a "last chosen" entry (!always) 3886 PreferredActivity lastChosen = new PreferredActivity( 3887 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 3888 pir.addFilter(lastChosen); 3889 changed = true; 3890 return null; 3891 } 3892 3893 // Yay! Either the set matched or we're looking for the last chosen 3894 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 3895 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3896 return ri; 3897 } 3898 } 3899 } finally { 3900 if (changed) { 3901 if (DEBUG_PREFERRED) { 3902 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 3903 } 3904 scheduleWritePackageRestrictionsLocked(userId); 3905 } 3906 } 3907 } 3908 } 3909 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 3910 return null; 3911 } 3912 3913 /* 3914 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 3915 */ 3916 @Override 3917 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 3918 int targetUserId) { 3919 mContext.enforceCallingOrSelfPermission( 3920 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 3921 List<CrossProfileIntentFilter> matches = 3922 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 3923 if (matches != null) { 3924 int size = matches.size(); 3925 for (int i = 0; i < size; i++) { 3926 if (matches.get(i).getTargetUserId() == targetUserId) return true; 3927 } 3928 } 3929 return false; 3930 } 3931 3932 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 3933 String resolvedType, int userId) { 3934 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 3935 if (resolver != null) { 3936 return resolver.queryIntent(intent, resolvedType, false, userId); 3937 } 3938 return null; 3939 } 3940 3941 @Override 3942 public List<ResolveInfo> queryIntentActivities(Intent intent, 3943 String resolvedType, int flags, int userId) { 3944 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3945 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 3946 ComponentName comp = intent.getComponent(); 3947 if (comp == null) { 3948 if (intent.getSelector() != null) { 3949 intent = intent.getSelector(); 3950 comp = intent.getComponent(); 3951 } 3952 } 3953 3954 if (comp != null) { 3955 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3956 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 3957 if (ai != null) { 3958 final ResolveInfo ri = new ResolveInfo(); 3959 ri.activityInfo = ai; 3960 list.add(ri); 3961 } 3962 return list; 3963 } 3964 3965 // reader 3966 synchronized (mPackages) { 3967 final String pkgName = intent.getPackage(); 3968 if (pkgName == null) { 3969 List<CrossProfileIntentFilter> matchingFilters = 3970 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 3971 // Check for results that need to skip the current profile. 3972 ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 3973 resolvedType, flags, userId); 3974 if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { 3975 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 3976 result.add(resolveInfo); 3977 return filterIfNotPrimaryUser(result, userId); 3978 } 3979 3980 // Check for results in the current profile. 3981 List<ResolveInfo> result = mActivities.queryIntent( 3982 intent, resolvedType, flags, userId); 3983 3984 // Check for cross profile results. 3985 resolveInfo = queryCrossProfileIntents( 3986 matchingFilters, intent, resolvedType, flags, userId); 3987 if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { 3988 result.add(resolveInfo); 3989 Collections.sort(result, mResolvePrioritySorter); 3990 } 3991 result = filterIfNotPrimaryUser(result, userId); 3992 if (result.size() > 1 && hasWebURI(intent)) { 3993 return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result); 3994 } 3995 return result; 3996 } 3997 final PackageParser.Package pkg = mPackages.get(pkgName); 3998 if (pkg != null) { 3999 return filterIfNotPrimaryUser( 4000 mActivities.queryIntentForPackage( 4001 intent, resolvedType, flags, pkg.activities, userId), 4002 userId); 4003 } 4004 return new ArrayList<ResolveInfo>(); 4005 } 4006 } 4007 4008 private boolean isUserEnabled(int userId) { 4009 long callingId = Binder.clearCallingIdentity(); 4010 try { 4011 UserInfo userInfo = sUserManager.getUserInfo(userId); 4012 return userInfo != null && userInfo.isEnabled(); 4013 } finally { 4014 Binder.restoreCallingIdentity(callingId); 4015 } 4016 } 4017 4018 /** 4019 * Filter out activities with primaryUserOnly flag set, when current user is not the owner. 4020 * 4021 * @return filtered list 4022 */ 4023 private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) { 4024 if (userId == UserHandle.USER_OWNER) { 4025 return resolveInfos; 4026 } 4027 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 4028 ResolveInfo info = resolveInfos.get(i); 4029 if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 4030 resolveInfos.remove(i); 4031 } 4032 } 4033 return resolveInfos; 4034 } 4035 4036 private static boolean hasWebURI(Intent intent) { 4037 if (intent.getData() == null) { 4038 return false; 4039 } 4040 final String scheme = intent.getScheme(); 4041 if (TextUtils.isEmpty(scheme)) { 4042 return false; 4043 } 4044 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 4045 } 4046 4047 private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr( 4048 int flags, List<ResolveInfo> candidates) { 4049 if (DEBUG_PREFERRED) { 4050 Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " + 4051 candidates.size()); 4052 } 4053 4054 final int userId = UserHandle.getCallingUserId(); 4055 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 4056 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 4057 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 4058 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 4059 4060 synchronized (mPackages) { 4061 final int count = candidates.size(); 4062 // First, try to use the domain prefered App 4063 for (int n=0; n<count; n++) { 4064 ResolveInfo info = candidates.get(n); 4065 String packageName = info.activityInfo.packageName; 4066 PackageSetting ps = mSettings.mPackages.get(packageName); 4067 if (ps != null) { 4068 // Add to the special match all list (Browser use case) 4069 if (info.handleAllWebDataURI) { 4070 matchAllList.add(info); 4071 continue; 4072 } 4073 // Try to get the status from User settings first 4074 int status = getDomainVerificationStatusLPr(ps, userId); 4075 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 4076 result.add(info); 4077 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4078 neverList.add(info); 4079 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4080 undefinedList.add(info); 4081 } 4082 } 4083 } 4084 // If there is nothing selected, add all candidates and remove the ones that the User 4085 // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and 4086 // also remove any Browser Apps ones. 4087 // If there is still none after this pass, add all undefined one and Browser Apps and 4088 // let the User decide with the Disambiguation dialog if there are several ones. 4089 if (result.size() == 0) { 4090 result.addAll(candidates); 4091 } 4092 result.removeAll(neverList); 4093 result.removeAll(matchAllList); 4094 if (result.size() == 0) { 4095 result.addAll(undefinedList); 4096 if ((flags & MATCH_ALL) != 0) { 4097 result.addAll(matchAllList); 4098 } else { 4099 // Try to add the Default Browser if we can 4100 final String defaultBrowserPackageName = getDefaultBrowserPackageName( 4101 UserHandle.myUserId()); 4102 if (!TextUtils.isEmpty(defaultBrowserPackageName)) { 4103 boolean defaultBrowserFound = false; 4104 final int browserCount = matchAllList.size(); 4105 for (int n=0; n<browserCount; n++) { 4106 ResolveInfo browser = matchAllList.get(n); 4107 if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) { 4108 result.add(browser); 4109 defaultBrowserFound = true; 4110 break; 4111 } 4112 } 4113 if (!defaultBrowserFound) { 4114 result.addAll(matchAllList); 4115 } 4116 } else { 4117 result.addAll(matchAllList); 4118 } 4119 } 4120 } 4121 } 4122 if (DEBUG_PREFERRED) { 4123 Slog.v("TAG", "Filtered results with prefered activities. New candidates count: " + 4124 result.size()); 4125 } 4126 return result; 4127 } 4128 4129 private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 4130 int status = ps.getDomainVerificationStatusForUser(userId); 4131 // if none available, get the master status 4132 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4133 if (ps.getIntentFilterVerificationInfo() != null) { 4134 status = ps.getIntentFilterVerificationInfo().getStatus(); 4135 } 4136 } 4137 return status; 4138 } 4139 4140 private ResolveInfo querySkipCurrentProfileIntents( 4141 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4142 int flags, int sourceUserId) { 4143 if (matchingFilters != null) { 4144 int size = matchingFilters.size(); 4145 for (int i = 0; i < size; i ++) { 4146 CrossProfileIntentFilter filter = matchingFilters.get(i); 4147 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 4148 // Checking if there are activities in the target user that can handle the 4149 // intent. 4150 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4151 flags, sourceUserId); 4152 if (resolveInfo != null) { 4153 return resolveInfo; 4154 } 4155 } 4156 } 4157 } 4158 return null; 4159 } 4160 4161 // Return matching ResolveInfo if any for skip current profile intent filters. 4162 private ResolveInfo queryCrossProfileIntents( 4163 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4164 int flags, int sourceUserId) { 4165 if (matchingFilters != null) { 4166 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 4167 // match the same intent. For performance reasons, it is better not to 4168 // run queryIntent twice for the same userId 4169 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 4170 int size = matchingFilters.size(); 4171 for (int i = 0; i < size; i++) { 4172 CrossProfileIntentFilter filter = matchingFilters.get(i); 4173 int targetUserId = filter.getTargetUserId(); 4174 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 4175 && !alreadyTriedUserIds.get(targetUserId)) { 4176 // Checking if there are activities in the target user that can handle the 4177 // intent. 4178 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4179 flags, sourceUserId); 4180 if (resolveInfo != null) return resolveInfo; 4181 alreadyTriedUserIds.put(targetUserId, true); 4182 } 4183 } 4184 } 4185 return null; 4186 } 4187 4188 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 4189 String resolvedType, int flags, int sourceUserId) { 4190 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4191 resolvedType, flags, filter.getTargetUserId()); 4192 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 4193 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 4194 } 4195 return null; 4196 } 4197 4198 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 4199 int sourceUserId, int targetUserId) { 4200 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 4201 String className; 4202 if (targetUserId == UserHandle.USER_OWNER) { 4203 className = FORWARD_INTENT_TO_USER_OWNER; 4204 } else { 4205 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 4206 } 4207 ComponentName forwardingActivityComponentName = new ComponentName( 4208 mAndroidApplication.packageName, className); 4209 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 4210 sourceUserId); 4211 if (targetUserId == UserHandle.USER_OWNER) { 4212 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 4213 forwardingResolveInfo.noResourceId = true; 4214 } 4215 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 4216 forwardingResolveInfo.priority = 0; 4217 forwardingResolveInfo.preferredOrder = 0; 4218 forwardingResolveInfo.match = 0; 4219 forwardingResolveInfo.isDefault = true; 4220 forwardingResolveInfo.filter = filter; 4221 forwardingResolveInfo.targetUserId = targetUserId; 4222 return forwardingResolveInfo; 4223 } 4224 4225 @Override 4226 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 4227 Intent[] specifics, String[] specificTypes, Intent intent, 4228 String resolvedType, int flags, int userId) { 4229 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4230 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 4231 false, "query intent activity options"); 4232 final String resultsAction = intent.getAction(); 4233 4234 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 4235 | PackageManager.GET_RESOLVED_FILTER, userId); 4236 4237 if (DEBUG_INTENT_MATCHING) { 4238 Log.v(TAG, "Query " + intent + ": " + results); 4239 } 4240 4241 int specificsPos = 0; 4242 int N; 4243 4244 // todo: note that the algorithm used here is O(N^2). This 4245 // isn't a problem in our current environment, but if we start running 4246 // into situations where we have more than 5 or 10 matches then this 4247 // should probably be changed to something smarter... 4248 4249 // First we go through and resolve each of the specific items 4250 // that were supplied, taking care of removing any corresponding 4251 // duplicate items in the generic resolve list. 4252 if (specifics != null) { 4253 for (int i=0; i<specifics.length; i++) { 4254 final Intent sintent = specifics[i]; 4255 if (sintent == null) { 4256 continue; 4257 } 4258 4259 if (DEBUG_INTENT_MATCHING) { 4260 Log.v(TAG, "Specific #" + i + ": " + sintent); 4261 } 4262 4263 String action = sintent.getAction(); 4264 if (resultsAction != null && resultsAction.equals(action)) { 4265 // If this action was explicitly requested, then don't 4266 // remove things that have it. 4267 action = null; 4268 } 4269 4270 ResolveInfo ri = null; 4271 ActivityInfo ai = null; 4272 4273 ComponentName comp = sintent.getComponent(); 4274 if (comp == null) { 4275 ri = resolveIntent( 4276 sintent, 4277 specificTypes != null ? specificTypes[i] : null, 4278 flags, userId); 4279 if (ri == null) { 4280 continue; 4281 } 4282 if (ri == mResolveInfo) { 4283 // ACK! Must do something better with this. 4284 } 4285 ai = ri.activityInfo; 4286 comp = new ComponentName(ai.applicationInfo.packageName, 4287 ai.name); 4288 } else { 4289 ai = getActivityInfo(comp, flags, userId); 4290 if (ai == null) { 4291 continue; 4292 } 4293 } 4294 4295 // Look for any generic query activities that are duplicates 4296 // of this specific one, and remove them from the results. 4297 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 4298 N = results.size(); 4299 int j; 4300 for (j=specificsPos; j<N; j++) { 4301 ResolveInfo sri = results.get(j); 4302 if ((sri.activityInfo.name.equals(comp.getClassName()) 4303 && sri.activityInfo.applicationInfo.packageName.equals( 4304 comp.getPackageName())) 4305 || (action != null && sri.filter.matchAction(action))) { 4306 results.remove(j); 4307 if (DEBUG_INTENT_MATCHING) Log.v( 4308 TAG, "Removing duplicate item from " + j 4309 + " due to specific " + specificsPos); 4310 if (ri == null) { 4311 ri = sri; 4312 } 4313 j--; 4314 N--; 4315 } 4316 } 4317 4318 // Add this specific item to its proper place. 4319 if (ri == null) { 4320 ri = new ResolveInfo(); 4321 ri.activityInfo = ai; 4322 } 4323 results.add(specificsPos, ri); 4324 ri.specificIndex = i; 4325 specificsPos++; 4326 } 4327 } 4328 4329 // Now we go through the remaining generic results and remove any 4330 // duplicate actions that are found here. 4331 N = results.size(); 4332 for (int i=specificsPos; i<N-1; i++) { 4333 final ResolveInfo rii = results.get(i); 4334 if (rii.filter == null) { 4335 continue; 4336 } 4337 4338 // Iterate over all of the actions of this result's intent 4339 // filter... typically this should be just one. 4340 final Iterator<String> it = rii.filter.actionsIterator(); 4341 if (it == null) { 4342 continue; 4343 } 4344 while (it.hasNext()) { 4345 final String action = it.next(); 4346 if (resultsAction != null && resultsAction.equals(action)) { 4347 // If this action was explicitly requested, then don't 4348 // remove things that have it. 4349 continue; 4350 } 4351 for (int j=i+1; j<N; j++) { 4352 final ResolveInfo rij = results.get(j); 4353 if (rij.filter != null && rij.filter.hasAction(action)) { 4354 results.remove(j); 4355 if (DEBUG_INTENT_MATCHING) Log.v( 4356 TAG, "Removing duplicate item from " + j 4357 + " due to action " + action + " at " + i); 4358 j--; 4359 N--; 4360 } 4361 } 4362 } 4363 4364 // If the caller didn't request filter information, drop it now 4365 // so we don't have to marshall/unmarshall it. 4366 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4367 rii.filter = null; 4368 } 4369 } 4370 4371 // Filter out the caller activity if so requested. 4372 if (caller != null) { 4373 N = results.size(); 4374 for (int i=0; i<N; i++) { 4375 ActivityInfo ainfo = results.get(i).activityInfo; 4376 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 4377 && caller.getClassName().equals(ainfo.name)) { 4378 results.remove(i); 4379 break; 4380 } 4381 } 4382 } 4383 4384 // If the caller didn't request filter information, 4385 // drop them now so we don't have to 4386 // marshall/unmarshall it. 4387 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4388 N = results.size(); 4389 for (int i=0; i<N; i++) { 4390 results.get(i).filter = null; 4391 } 4392 } 4393 4394 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 4395 return results; 4396 } 4397 4398 @Override 4399 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 4400 int userId) { 4401 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4402 ComponentName comp = intent.getComponent(); 4403 if (comp == null) { 4404 if (intent.getSelector() != null) { 4405 intent = intent.getSelector(); 4406 comp = intent.getComponent(); 4407 } 4408 } 4409 if (comp != null) { 4410 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4411 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 4412 if (ai != null) { 4413 ResolveInfo ri = new ResolveInfo(); 4414 ri.activityInfo = ai; 4415 list.add(ri); 4416 } 4417 return list; 4418 } 4419 4420 // reader 4421 synchronized (mPackages) { 4422 String pkgName = intent.getPackage(); 4423 if (pkgName == null) { 4424 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 4425 } 4426 final PackageParser.Package pkg = mPackages.get(pkgName); 4427 if (pkg != null) { 4428 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 4429 userId); 4430 } 4431 return null; 4432 } 4433 } 4434 4435 @Override 4436 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 4437 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 4438 if (!sUserManager.exists(userId)) return null; 4439 if (query != null) { 4440 if (query.size() >= 1) { 4441 // If there is more than one service with the same priority, 4442 // just arbitrarily pick the first one. 4443 return query.get(0); 4444 } 4445 } 4446 return null; 4447 } 4448 4449 @Override 4450 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 4451 int userId) { 4452 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4453 ComponentName comp = intent.getComponent(); 4454 if (comp == null) { 4455 if (intent.getSelector() != null) { 4456 intent = intent.getSelector(); 4457 comp = intent.getComponent(); 4458 } 4459 } 4460 if (comp != null) { 4461 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4462 final ServiceInfo si = getServiceInfo(comp, flags, userId); 4463 if (si != null) { 4464 final ResolveInfo ri = new ResolveInfo(); 4465 ri.serviceInfo = si; 4466 list.add(ri); 4467 } 4468 return list; 4469 } 4470 4471 // reader 4472 synchronized (mPackages) { 4473 String pkgName = intent.getPackage(); 4474 if (pkgName == null) { 4475 return mServices.queryIntent(intent, resolvedType, flags, userId); 4476 } 4477 final PackageParser.Package pkg = mPackages.get(pkgName); 4478 if (pkg != null) { 4479 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 4480 userId); 4481 } 4482 return null; 4483 } 4484 } 4485 4486 @Override 4487 public List<ResolveInfo> queryIntentContentProviders( 4488 Intent intent, String resolvedType, int flags, int userId) { 4489 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4490 ComponentName comp = intent.getComponent(); 4491 if (comp == null) { 4492 if (intent.getSelector() != null) { 4493 intent = intent.getSelector(); 4494 comp = intent.getComponent(); 4495 } 4496 } 4497 if (comp != null) { 4498 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4499 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 4500 if (pi != null) { 4501 final ResolveInfo ri = new ResolveInfo(); 4502 ri.providerInfo = pi; 4503 list.add(ri); 4504 } 4505 return list; 4506 } 4507 4508 // reader 4509 synchronized (mPackages) { 4510 String pkgName = intent.getPackage(); 4511 if (pkgName == null) { 4512 return mProviders.queryIntent(intent, resolvedType, flags, userId); 4513 } 4514 final PackageParser.Package pkg = mPackages.get(pkgName); 4515 if (pkg != null) { 4516 return mProviders.queryIntentForPackage( 4517 intent, resolvedType, flags, pkg.providers, userId); 4518 } 4519 return null; 4520 } 4521 } 4522 4523 @Override 4524 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 4525 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4526 4527 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 4528 4529 // writer 4530 synchronized (mPackages) { 4531 ArrayList<PackageInfo> list; 4532 if (listUninstalled) { 4533 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 4534 for (PackageSetting ps : mSettings.mPackages.values()) { 4535 PackageInfo pi; 4536 if (ps.pkg != null) { 4537 pi = generatePackageInfo(ps.pkg, flags, userId); 4538 } else { 4539 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4540 } 4541 if (pi != null) { 4542 list.add(pi); 4543 } 4544 } 4545 } else { 4546 list = new ArrayList<PackageInfo>(mPackages.size()); 4547 for (PackageParser.Package p : mPackages.values()) { 4548 PackageInfo pi = generatePackageInfo(p, flags, userId); 4549 if (pi != null) { 4550 list.add(pi); 4551 } 4552 } 4553 } 4554 4555 return new ParceledListSlice<PackageInfo>(list); 4556 } 4557 } 4558 4559 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 4560 String[] permissions, boolean[] tmp, int flags, int userId) { 4561 int numMatch = 0; 4562 final PermissionsState permissionsState = ps.getPermissionsState(); 4563 for (int i=0; i<permissions.length; i++) { 4564 final String permission = permissions[i]; 4565 if (permissionsState.hasPermission(permission, userId)) { 4566 tmp[i] = true; 4567 numMatch++; 4568 } else { 4569 tmp[i] = false; 4570 } 4571 } 4572 if (numMatch == 0) { 4573 return; 4574 } 4575 PackageInfo pi; 4576 if (ps.pkg != null) { 4577 pi = generatePackageInfo(ps.pkg, flags, userId); 4578 } else { 4579 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4580 } 4581 // The above might return null in cases of uninstalled apps or install-state 4582 // skew across users/profiles. 4583 if (pi != null) { 4584 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 4585 if (numMatch == permissions.length) { 4586 pi.requestedPermissions = permissions; 4587 } else { 4588 pi.requestedPermissions = new String[numMatch]; 4589 numMatch = 0; 4590 for (int i=0; i<permissions.length; i++) { 4591 if (tmp[i]) { 4592 pi.requestedPermissions[numMatch] = permissions[i]; 4593 numMatch++; 4594 } 4595 } 4596 } 4597 } 4598 list.add(pi); 4599 } 4600 } 4601 4602 @Override 4603 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 4604 String[] permissions, int flags, int userId) { 4605 if (!sUserManager.exists(userId)) return null; 4606 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4607 4608 // writer 4609 synchronized (mPackages) { 4610 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 4611 boolean[] tmpBools = new boolean[permissions.length]; 4612 if (listUninstalled) { 4613 for (PackageSetting ps : mSettings.mPackages.values()) { 4614 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 4615 } 4616 } else { 4617 for (PackageParser.Package pkg : mPackages.values()) { 4618 PackageSetting ps = (PackageSetting)pkg.mExtras; 4619 if (ps != null) { 4620 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 4621 userId); 4622 } 4623 } 4624 } 4625 4626 return new ParceledListSlice<PackageInfo>(list); 4627 } 4628 } 4629 4630 @Override 4631 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 4632 if (!sUserManager.exists(userId)) return null; 4633 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4634 4635 // writer 4636 synchronized (mPackages) { 4637 ArrayList<ApplicationInfo> list; 4638 if (listUninstalled) { 4639 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 4640 for (PackageSetting ps : mSettings.mPackages.values()) { 4641 ApplicationInfo ai; 4642 if (ps.pkg != null) { 4643 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 4644 ps.readUserState(userId), userId); 4645 } else { 4646 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 4647 } 4648 if (ai != null) { 4649 list.add(ai); 4650 } 4651 } 4652 } else { 4653 list = new ArrayList<ApplicationInfo>(mPackages.size()); 4654 for (PackageParser.Package p : mPackages.values()) { 4655 if (p.mExtras != null) { 4656 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4657 ((PackageSetting)p.mExtras).readUserState(userId), userId); 4658 if (ai != null) { 4659 list.add(ai); 4660 } 4661 } 4662 } 4663 } 4664 4665 return new ParceledListSlice<ApplicationInfo>(list); 4666 } 4667 } 4668 4669 public List<ApplicationInfo> getPersistentApplications(int flags) { 4670 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 4671 4672 // reader 4673 synchronized (mPackages) { 4674 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 4675 final int userId = UserHandle.getCallingUserId(); 4676 while (i.hasNext()) { 4677 final PackageParser.Package p = i.next(); 4678 if (p.applicationInfo != null 4679 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 4680 && (!mSafeMode || isSystemApp(p))) { 4681 PackageSetting ps = mSettings.mPackages.get(p.packageName); 4682 if (ps != null) { 4683 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4684 ps.readUserState(userId), userId); 4685 if (ai != null) { 4686 finalList.add(ai); 4687 } 4688 } 4689 } 4690 } 4691 } 4692 4693 return finalList; 4694 } 4695 4696 @Override 4697 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 4698 if (!sUserManager.exists(userId)) return null; 4699 // reader 4700 synchronized (mPackages) { 4701 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 4702 PackageSetting ps = provider != null 4703 ? mSettings.mPackages.get(provider.owner.packageName) 4704 : null; 4705 return ps != null 4706 && mSettings.isEnabledLPr(provider.info, flags, userId) 4707 && (!mSafeMode || (provider.info.applicationInfo.flags 4708 &ApplicationInfo.FLAG_SYSTEM) != 0) 4709 ? PackageParser.generateProviderInfo(provider, flags, 4710 ps.readUserState(userId), userId) 4711 : null; 4712 } 4713 } 4714 4715 /** 4716 * @deprecated 4717 */ 4718 @Deprecated 4719 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 4720 // reader 4721 synchronized (mPackages) { 4722 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 4723 .entrySet().iterator(); 4724 final int userId = UserHandle.getCallingUserId(); 4725 while (i.hasNext()) { 4726 Map.Entry<String, PackageParser.Provider> entry = i.next(); 4727 PackageParser.Provider p = entry.getValue(); 4728 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4729 4730 if (ps != null && p.syncable 4731 && (!mSafeMode || (p.info.applicationInfo.flags 4732 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 4733 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 4734 ps.readUserState(userId), userId); 4735 if (info != null) { 4736 outNames.add(entry.getKey()); 4737 outInfo.add(info); 4738 } 4739 } 4740 } 4741 } 4742 } 4743 4744 @Override 4745 public List<ProviderInfo> queryContentProviders(String processName, 4746 int uid, int flags) { 4747 ArrayList<ProviderInfo> finalList = null; 4748 // reader 4749 synchronized (mPackages) { 4750 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 4751 final int userId = processName != null ? 4752 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 4753 while (i.hasNext()) { 4754 final PackageParser.Provider p = i.next(); 4755 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4756 if (ps != null && p.info.authority != null 4757 && (processName == null 4758 || (p.info.processName.equals(processName) 4759 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 4760 && mSettings.isEnabledLPr(p.info, flags, userId) 4761 && (!mSafeMode 4762 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 4763 if (finalList == null) { 4764 finalList = new ArrayList<ProviderInfo>(3); 4765 } 4766 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 4767 ps.readUserState(userId), userId); 4768 if (info != null) { 4769 finalList.add(info); 4770 } 4771 } 4772 } 4773 } 4774 4775 if (finalList != null) { 4776 Collections.sort(finalList, mProviderInitOrderSorter); 4777 } 4778 4779 return finalList; 4780 } 4781 4782 @Override 4783 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 4784 int flags) { 4785 // reader 4786 synchronized (mPackages) { 4787 final PackageParser.Instrumentation i = mInstrumentation.get(name); 4788 return PackageParser.generateInstrumentationInfo(i, flags); 4789 } 4790 } 4791 4792 @Override 4793 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 4794 int flags) { 4795 ArrayList<InstrumentationInfo> finalList = 4796 new ArrayList<InstrumentationInfo>(); 4797 4798 // reader 4799 synchronized (mPackages) { 4800 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 4801 while (i.hasNext()) { 4802 final PackageParser.Instrumentation p = i.next(); 4803 if (targetPackage == null 4804 || targetPackage.equals(p.info.targetPackage)) { 4805 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 4806 flags); 4807 if (ii != null) { 4808 finalList.add(ii); 4809 } 4810 } 4811 } 4812 } 4813 4814 return finalList; 4815 } 4816 4817 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 4818 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 4819 if (overlays == null) { 4820 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 4821 return; 4822 } 4823 for (PackageParser.Package opkg : overlays.values()) { 4824 // Not much to do if idmap fails: we already logged the error 4825 // and we certainly don't want to abort installation of pkg simply 4826 // because an overlay didn't fit properly. For these reasons, 4827 // ignore the return value of createIdmapForPackagePairLI. 4828 createIdmapForPackagePairLI(pkg, opkg); 4829 } 4830 } 4831 4832 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 4833 PackageParser.Package opkg) { 4834 if (!opkg.mTrustedOverlay) { 4835 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 4836 opkg.baseCodePath + ": overlay not trusted"); 4837 return false; 4838 } 4839 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 4840 if (overlaySet == null) { 4841 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 4842 opkg.baseCodePath + " but target package has no known overlays"); 4843 return false; 4844 } 4845 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4846 // TODO: generate idmap for split APKs 4847 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 4848 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 4849 + opkg.baseCodePath); 4850 return false; 4851 } 4852 PackageParser.Package[] overlayArray = 4853 overlaySet.values().toArray(new PackageParser.Package[0]); 4854 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 4855 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 4856 return p1.mOverlayPriority - p2.mOverlayPriority; 4857 } 4858 }; 4859 Arrays.sort(overlayArray, cmp); 4860 4861 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 4862 int i = 0; 4863 for (PackageParser.Package p : overlayArray) { 4864 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 4865 } 4866 return true; 4867 } 4868 4869 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 4870 final File[] files = dir.listFiles(); 4871 if (ArrayUtils.isEmpty(files)) { 4872 Log.d(TAG, "No files in app dir " + dir); 4873 return; 4874 } 4875 4876 if (DEBUG_PACKAGE_SCANNING) { 4877 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 4878 + " flags=0x" + Integer.toHexString(parseFlags)); 4879 } 4880 4881 for (File file : files) { 4882 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 4883 && !PackageInstallerService.isStageName(file.getName()); 4884 if (!isPackage) { 4885 // Ignore entries which are not packages 4886 continue; 4887 } 4888 try { 4889 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 4890 scanFlags, currentTime, null); 4891 } catch (PackageManagerException e) { 4892 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 4893 4894 // Delete invalid userdata apps 4895 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 4896 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 4897 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 4898 if (file.isDirectory()) { 4899 mInstaller.rmPackageDir(file.getAbsolutePath()); 4900 } else { 4901 file.delete(); 4902 } 4903 } 4904 } 4905 } 4906 } 4907 4908 private static File getSettingsProblemFile() { 4909 File dataDir = Environment.getDataDirectory(); 4910 File systemDir = new File(dataDir, "system"); 4911 File fname = new File(systemDir, "uiderrors.txt"); 4912 return fname; 4913 } 4914 4915 static void reportSettingsProblem(int priority, String msg) { 4916 logCriticalInfo(priority, msg); 4917 } 4918 4919 static void logCriticalInfo(int priority, String msg) { 4920 Slog.println(priority, TAG, msg); 4921 EventLogTags.writePmCriticalInfo(msg); 4922 try { 4923 File fname = getSettingsProblemFile(); 4924 FileOutputStream out = new FileOutputStream(fname, true); 4925 PrintWriter pw = new FastPrintWriter(out); 4926 SimpleDateFormat formatter = new SimpleDateFormat(); 4927 String dateString = formatter.format(new Date(System.currentTimeMillis())); 4928 pw.println(dateString + ": " + msg); 4929 pw.close(); 4930 FileUtils.setPermissions( 4931 fname.toString(), 4932 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 4933 -1, -1); 4934 } catch (java.io.IOException e) { 4935 } 4936 } 4937 4938 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 4939 PackageParser.Package pkg, File srcFile, int parseFlags) 4940 throws PackageManagerException { 4941 if (ps != null 4942 && ps.codePath.equals(srcFile) 4943 && ps.timeStamp == srcFile.lastModified() 4944 && !isCompatSignatureUpdateNeeded(pkg) 4945 && !isRecoverSignatureUpdateNeeded(pkg)) { 4946 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 4947 if (ps.signatures.mSignatures != null 4948 && ps.signatures.mSignatures.length != 0 4949 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) { 4950 // Optimization: reuse the existing cached certificates 4951 // if the package appears to be unchanged. 4952 pkg.mSignatures = ps.signatures.mSignatures; 4953 KeySetManagerService ksms = mSettings.mKeySetManagerService; 4954 synchronized (mPackages) { 4955 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 4956 } 4957 return; 4958 } 4959 4960 Slog.w(TAG, "PackageSetting for " + ps.name 4961 + " is missing signatures. Collecting certs again to recover them."); 4962 } else { 4963 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 4964 } 4965 4966 try { 4967 pp.collectCertificates(pkg, parseFlags); 4968 pp.collectManifestDigest(pkg); 4969 } catch (PackageParserException e) { 4970 throw PackageManagerException.from(e); 4971 } 4972 } 4973 4974 /* 4975 * Scan a package and return the newly parsed package. 4976 * Returns null in case of errors and the error code is stored in mLastScanError 4977 */ 4978 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 4979 long currentTime, UserHandle user) throws PackageManagerException { 4980 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 4981 parseFlags |= mDefParseFlags; 4982 PackageParser pp = new PackageParser(); 4983 pp.setSeparateProcesses(mSeparateProcesses); 4984 pp.setOnlyCoreApps(mOnlyCore); 4985 pp.setDisplayMetrics(mMetrics); 4986 4987 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 4988 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 4989 } 4990 4991 final PackageParser.Package pkg; 4992 try { 4993 pkg = pp.parsePackage(scanFile, parseFlags); 4994 } catch (PackageParserException e) { 4995 throw PackageManagerException.from(e); 4996 } 4997 4998 PackageSetting ps = null; 4999 PackageSetting updatedPkg; 5000 // reader 5001 synchronized (mPackages) { 5002 // Look to see if we already know about this package. 5003 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 5004 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 5005 // This package has been renamed to its original name. Let's 5006 // use that. 5007 ps = mSettings.peekPackageLPr(oldName); 5008 } 5009 // If there was no original package, see one for the real package name. 5010 if (ps == null) { 5011 ps = mSettings.peekPackageLPr(pkg.packageName); 5012 } 5013 // Check to see if this package could be hiding/updating a system 5014 // package. Must look for it either under the original or real 5015 // package name depending on our state. 5016 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 5017 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 5018 } 5019 boolean updatedPkgBetter = false; 5020 // First check if this is a system package that may involve an update 5021 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5022 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 5023 // it needs to drop FLAG_PRIVILEGED. 5024 if (locationIsPrivileged(scanFile)) { 5025 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5026 } else { 5027 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5028 } 5029 5030 if (ps != null && !ps.codePath.equals(scanFile)) { 5031 // The path has changed from what was last scanned... check the 5032 // version of the new path against what we have stored to determine 5033 // what to do. 5034 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 5035 if (pkg.mVersionCode <= ps.versionCode) { 5036 // The system package has been updated and the code path does not match 5037 // Ignore entry. Skip it. 5038 Slog.i(TAG, "Package " + ps.name + " at " + scanFile 5039 + " ignored: updated version " + ps.versionCode 5040 + " better than this " + pkg.mVersionCode); 5041 if (!updatedPkg.codePath.equals(scanFile)) { 5042 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 5043 + ps.name + " changing from " + updatedPkg.codePathString 5044 + " to " + scanFile); 5045 updatedPkg.codePath = scanFile; 5046 updatedPkg.codePathString = scanFile.toString(); 5047 updatedPkg.resourcePath = scanFile; 5048 updatedPkg.resourcePathString = scanFile.toString(); 5049 } 5050 updatedPkg.pkg = pkg; 5051 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null); 5052 } else { 5053 // The current app on the system partition is better than 5054 // what we have updated to on the data partition; switch 5055 // back to the system partition version. 5056 // At this point, its safely assumed that package installation for 5057 // apps in system partition will go through. If not there won't be a working 5058 // version of the app 5059 // writer 5060 synchronized (mPackages) { 5061 // Just remove the loaded entries from package lists. 5062 mPackages.remove(ps.name); 5063 } 5064 5065 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5066 + " reverting from " + ps.codePathString 5067 + ": new version " + pkg.mVersionCode 5068 + " better than installed " + ps.versionCode); 5069 5070 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5071 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5072 synchronized (mInstallLock) { 5073 args.cleanUpResourcesLI(); 5074 } 5075 synchronized (mPackages) { 5076 mSettings.enableSystemPackageLPw(ps.name); 5077 } 5078 updatedPkgBetter = true; 5079 } 5080 } 5081 } 5082 5083 if (updatedPkg != null) { 5084 // An updated system app will not have the PARSE_IS_SYSTEM flag set 5085 // initially 5086 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 5087 5088 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 5089 // flag set initially 5090 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 5091 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 5092 } 5093 } 5094 5095 // Verify certificates against what was last scanned 5096 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 5097 5098 /* 5099 * A new system app appeared, but we already had a non-system one of the 5100 * same name installed earlier. 5101 */ 5102 boolean shouldHideSystemApp = false; 5103 if (updatedPkg == null && ps != null 5104 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 5105 /* 5106 * Check to make sure the signatures match first. If they don't, 5107 * wipe the installed application and its data. 5108 */ 5109 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 5110 != PackageManager.SIGNATURE_MATCH) { 5111 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 5112 + " signatures don't match existing userdata copy; removing"); 5113 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 5114 ps = null; 5115 } else { 5116 /* 5117 * If the newly-added system app is an older version than the 5118 * already installed version, hide it. It will be scanned later 5119 * and re-added like an update. 5120 */ 5121 if (pkg.mVersionCode <= ps.versionCode) { 5122 shouldHideSystemApp = true; 5123 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 5124 + " but new version " + pkg.mVersionCode + " better than installed " 5125 + ps.versionCode + "; hiding system"); 5126 } else { 5127 /* 5128 * The newly found system app is a newer version that the 5129 * one previously installed. Simply remove the 5130 * already-installed application and replace it with our own 5131 * while keeping the application data. 5132 */ 5133 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5134 + " reverting from " + ps.codePathString + ": new version " 5135 + pkg.mVersionCode + " better than installed " + ps.versionCode); 5136 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5137 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5138 synchronized (mInstallLock) { 5139 args.cleanUpResourcesLI(); 5140 } 5141 } 5142 } 5143 } 5144 5145 // The apk is forward locked (not public) if its code and resources 5146 // are kept in different files. (except for app in either system or 5147 // vendor path). 5148 // TODO grab this value from PackageSettings 5149 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5150 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 5151 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 5152 } 5153 } 5154 5155 // TODO: extend to support forward-locked splits 5156 String resourcePath = null; 5157 String baseResourcePath = null; 5158 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 5159 if (ps != null && ps.resourcePathString != null) { 5160 resourcePath = ps.resourcePathString; 5161 baseResourcePath = ps.resourcePathString; 5162 } else { 5163 // Should not happen at all. Just log an error. 5164 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 5165 } 5166 } else { 5167 resourcePath = pkg.codePath; 5168 baseResourcePath = pkg.baseCodePath; 5169 } 5170 5171 // Set application objects path explicitly. 5172 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 5173 pkg.applicationInfo.setCodePath(pkg.codePath); 5174 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 5175 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 5176 pkg.applicationInfo.setResourcePath(resourcePath); 5177 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 5178 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 5179 5180 // Note that we invoke the following method only if we are about to unpack an application 5181 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 5182 | SCAN_UPDATE_SIGNATURE, currentTime, user); 5183 5184 /* 5185 * If the system app should be overridden by a previously installed 5186 * data, hide the system app now and let the /data/app scan pick it up 5187 * again. 5188 */ 5189 if (shouldHideSystemApp) { 5190 synchronized (mPackages) { 5191 /* 5192 * We have to grant systems permissions before we hide, because 5193 * grantPermissions will assume the package update is trying to 5194 * expand its permissions. 5195 */ 5196 grantPermissionsLPw(pkg, true, pkg.packageName); 5197 mSettings.disableSystemPackageLPw(pkg.packageName); 5198 } 5199 } 5200 5201 return scannedPkg; 5202 } 5203 5204 private static String fixProcessName(String defProcessName, 5205 String processName, int uid) { 5206 if (processName == null) { 5207 return defProcessName; 5208 } 5209 return processName; 5210 } 5211 5212 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 5213 throws PackageManagerException { 5214 if (pkgSetting.signatures.mSignatures != null) { 5215 // Already existing package. Make sure signatures match 5216 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 5217 == PackageManager.SIGNATURE_MATCH; 5218 if (!match) { 5219 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 5220 == PackageManager.SIGNATURE_MATCH; 5221 } 5222 if (!match) { 5223 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 5224 == PackageManager.SIGNATURE_MATCH; 5225 } 5226 if (!match) { 5227 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5228 + pkg.packageName + " signatures do not match the " 5229 + "previously installed version; ignoring!"); 5230 } 5231 } 5232 5233 // Check for shared user signatures 5234 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 5235 // Already existing package. Make sure signatures match 5236 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5237 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 5238 if (!match) { 5239 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 5240 == PackageManager.SIGNATURE_MATCH; 5241 } 5242 if (!match) { 5243 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 5244 == PackageManager.SIGNATURE_MATCH; 5245 } 5246 if (!match) { 5247 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 5248 "Package " + pkg.packageName 5249 + " has no signatures that match those in shared user " 5250 + pkgSetting.sharedUser.name + "; ignoring!"); 5251 } 5252 } 5253 } 5254 5255 /** 5256 * Enforces that only the system UID or root's UID can call a method exposed 5257 * via Binder. 5258 * 5259 * @param message used as message if SecurityException is thrown 5260 * @throws SecurityException if the caller is not system or root 5261 */ 5262 private static final void enforceSystemOrRoot(String message) { 5263 final int uid = Binder.getCallingUid(); 5264 if (uid != Process.SYSTEM_UID && uid != 0) { 5265 throw new SecurityException(message); 5266 } 5267 } 5268 5269 @Override 5270 public void performBootDexOpt() { 5271 enforceSystemOrRoot("Only the system can request dexopt be performed"); 5272 5273 // Before everything else, see whether we need to fstrim. 5274 try { 5275 IMountService ms = PackageHelper.getMountService(); 5276 if (ms != null) { 5277 final boolean isUpgrade = isUpgrade(); 5278 boolean doTrim = isUpgrade; 5279 if (doTrim) { 5280 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 5281 } else { 5282 final long interval = android.provider.Settings.Global.getLong( 5283 mContext.getContentResolver(), 5284 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 5285 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 5286 if (interval > 0) { 5287 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 5288 if (timeSinceLast > interval) { 5289 doTrim = true; 5290 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 5291 + "; running immediately"); 5292 } 5293 } 5294 } 5295 if (doTrim) { 5296 if (!isFirstBoot()) { 5297 try { 5298 ActivityManagerNative.getDefault().showBootMessage( 5299 mContext.getResources().getString( 5300 R.string.android_upgrading_fstrim), true); 5301 } catch (RemoteException e) { 5302 } 5303 } 5304 ms.runMaintenance(); 5305 } 5306 } else { 5307 Slog.e(TAG, "Mount service unavailable!"); 5308 } 5309 } catch (RemoteException e) { 5310 // Can't happen; MountService is local 5311 } 5312 5313 final ArraySet<PackageParser.Package> pkgs; 5314 synchronized (mPackages) { 5315 pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages(); 5316 } 5317 5318 if (pkgs != null) { 5319 // Sort apps by importance for dexopt ordering. Important apps are given more priority 5320 // in case the device runs out of space. 5321 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 5322 // Give priority to core apps. 5323 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5324 PackageParser.Package pkg = it.next(); 5325 if (pkg.coreApp) { 5326 if (DEBUG_DEXOPT) { 5327 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 5328 } 5329 sortedPkgs.add(pkg); 5330 it.remove(); 5331 } 5332 } 5333 // Give priority to system apps that listen for pre boot complete. 5334 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 5335 ArraySet<String> pkgNames = getPackageNamesForIntent(intent); 5336 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5337 PackageParser.Package pkg = it.next(); 5338 if (pkgNames.contains(pkg.packageName)) { 5339 if (DEBUG_DEXOPT) { 5340 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 5341 } 5342 sortedPkgs.add(pkg); 5343 it.remove(); 5344 } 5345 } 5346 // Give priority to system apps. 5347 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5348 PackageParser.Package pkg = it.next(); 5349 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 5350 if (DEBUG_DEXOPT) { 5351 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName); 5352 } 5353 sortedPkgs.add(pkg); 5354 it.remove(); 5355 } 5356 } 5357 // Give priority to updated system apps. 5358 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5359 PackageParser.Package pkg = it.next(); 5360 if (pkg.isUpdatedSystemApp()) { 5361 if (DEBUG_DEXOPT) { 5362 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName); 5363 } 5364 sortedPkgs.add(pkg); 5365 it.remove(); 5366 } 5367 } 5368 // Give priority to apps that listen for boot complete. 5369 intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 5370 pkgNames = getPackageNamesForIntent(intent); 5371 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5372 PackageParser.Package pkg = it.next(); 5373 if (pkgNames.contains(pkg.packageName)) { 5374 if (DEBUG_DEXOPT) { 5375 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName); 5376 } 5377 sortedPkgs.add(pkg); 5378 it.remove(); 5379 } 5380 } 5381 // Filter out packages that aren't recently used. 5382 filterRecentlyUsedApps(pkgs); 5383 // Add all remaining apps. 5384 for (PackageParser.Package pkg : pkgs) { 5385 if (DEBUG_DEXOPT) { 5386 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 5387 } 5388 sortedPkgs.add(pkg); 5389 } 5390 5391 // If we want to be lazy, filter everything that wasn't recently used. 5392 if (mLazyDexOpt) { 5393 filterRecentlyUsedApps(sortedPkgs); 5394 } 5395 5396 int i = 0; 5397 int total = sortedPkgs.size(); 5398 File dataDir = Environment.getDataDirectory(); 5399 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 5400 if (lowThreshold == 0) { 5401 throw new IllegalStateException("Invalid low memory threshold"); 5402 } 5403 for (PackageParser.Package pkg : sortedPkgs) { 5404 long usableSpace = dataDir.getUsableSpace(); 5405 if (usableSpace < lowThreshold) { 5406 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 5407 break; 5408 } 5409 performBootDexOpt(pkg, ++i, total); 5410 } 5411 } 5412 } 5413 5414 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 5415 // Filter out packages that aren't recently used. 5416 // 5417 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 5418 // should do a full dexopt. 5419 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 5420 int total = pkgs.size(); 5421 int skipped = 0; 5422 long now = System.currentTimeMillis(); 5423 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 5424 PackageParser.Package pkg = i.next(); 5425 long then = pkg.mLastPackageUsageTimeInMills; 5426 if (then + mDexOptLRUThresholdInMills < now) { 5427 if (DEBUG_DEXOPT) { 5428 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 5429 ((then == 0) ? "never" : new Date(then))); 5430 } 5431 i.remove(); 5432 skipped++; 5433 } 5434 } 5435 if (DEBUG_DEXOPT) { 5436 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 5437 } 5438 } 5439 } 5440 5441 private ArraySet<String> getPackageNamesForIntent(Intent intent) { 5442 List<ResolveInfo> ris = null; 5443 try { 5444 ris = AppGlobals.getPackageManager().queryIntentReceivers( 5445 intent, null, 0, UserHandle.USER_OWNER); 5446 } catch (RemoteException e) { 5447 } 5448 ArraySet<String> pkgNames = new ArraySet<String>(); 5449 if (ris != null) { 5450 for (ResolveInfo ri : ris) { 5451 pkgNames.add(ri.activityInfo.packageName); 5452 } 5453 } 5454 return pkgNames; 5455 } 5456 5457 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 5458 if (DEBUG_DEXOPT) { 5459 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 5460 } 5461 if (!isFirstBoot()) { 5462 try { 5463 ActivityManagerNative.getDefault().showBootMessage( 5464 mContext.getResources().getString(R.string.android_upgrading_apk, 5465 curr, total), true); 5466 } catch (RemoteException e) { 5467 } 5468 } 5469 PackageParser.Package p = pkg; 5470 synchronized (mInstallLock) { 5471 mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, 5472 false /* force dex */, false /* defer */, true /* include dependencies */); 5473 } 5474 } 5475 5476 @Override 5477 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 5478 return performDexOpt(packageName, instructionSet, false); 5479 } 5480 5481 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) { 5482 boolean dexopt = mLazyDexOpt || backgroundDexopt; 5483 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 5484 if (!dexopt && !updateUsage) { 5485 // We aren't going to dexopt or update usage, so bail early. 5486 return false; 5487 } 5488 PackageParser.Package p; 5489 final String targetInstructionSet; 5490 synchronized (mPackages) { 5491 p = mPackages.get(packageName); 5492 if (p == null) { 5493 return false; 5494 } 5495 if (updateUsage) { 5496 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 5497 } 5498 mPackageUsage.write(false); 5499 if (!dexopt) { 5500 // We aren't going to dexopt, so bail early. 5501 return false; 5502 } 5503 5504 targetInstructionSet = instructionSet != null ? instructionSet : 5505 getPrimaryInstructionSet(p.applicationInfo); 5506 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 5507 return false; 5508 } 5509 } 5510 5511 synchronized (mInstallLock) { 5512 final String[] instructionSets = new String[] { targetInstructionSet }; 5513 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, 5514 false /* forceDex */, false /* defer */, true /* inclDependencies */); 5515 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 5516 } 5517 } 5518 5519 public ArraySet<String> getPackagesThatNeedDexOpt() { 5520 ArraySet<String> pkgs = null; 5521 synchronized (mPackages) { 5522 for (PackageParser.Package p : mPackages.values()) { 5523 if (DEBUG_DEXOPT) { 5524 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 5525 } 5526 if (!p.mDexOptPerformed.isEmpty()) { 5527 continue; 5528 } 5529 if (pkgs == null) { 5530 pkgs = new ArraySet<String>(); 5531 } 5532 pkgs.add(p.packageName); 5533 } 5534 } 5535 return pkgs; 5536 } 5537 5538 public void shutdown() { 5539 mPackageUsage.write(true); 5540 } 5541 5542 @Override 5543 public void forceDexOpt(String packageName) { 5544 enforceSystemOrRoot("forceDexOpt"); 5545 5546 PackageParser.Package pkg; 5547 synchronized (mPackages) { 5548 pkg = mPackages.get(packageName); 5549 if (pkg == null) { 5550 throw new IllegalArgumentException("Missing package: " + packageName); 5551 } 5552 } 5553 5554 synchronized (mInstallLock) { 5555 final String[] instructionSets = new String[] { 5556 getPrimaryInstructionSet(pkg.applicationInfo) }; 5557 final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, 5558 true /*forceDex*/, false /* defer */, true /* inclDependencies */); 5559 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 5560 throw new IllegalStateException("Failed to dexopt: " + res); 5561 } 5562 } 5563 } 5564 5565 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 5566 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 5567 Slog.w(TAG, "Unable to update from " + oldPkg.name 5568 + " to " + newPkg.packageName 5569 + ": old package not in system partition"); 5570 return false; 5571 } else if (mPackages.get(oldPkg.name) != null) { 5572 Slog.w(TAG, "Unable to update from " + oldPkg.name 5573 + " to " + newPkg.packageName 5574 + ": old package still exists"); 5575 return false; 5576 } 5577 return true; 5578 } 5579 5580 private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) { 5581 int[] users = sUserManager.getUserIds(); 5582 int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo); 5583 if (res < 0) { 5584 return res; 5585 } 5586 for (int user : users) { 5587 if (user != 0) { 5588 res = mInstaller.createUserData(volumeUuid, packageName, 5589 UserHandle.getUid(user, uid), user, seinfo); 5590 if (res < 0) { 5591 return res; 5592 } 5593 } 5594 } 5595 return res; 5596 } 5597 5598 private int removeDataDirsLI(String volumeUuid, String packageName) { 5599 int[] users = sUserManager.getUserIds(); 5600 int res = 0; 5601 for (int user : users) { 5602 int resInner = mInstaller.remove(volumeUuid, packageName, user); 5603 if (resInner < 0) { 5604 res = resInner; 5605 } 5606 } 5607 5608 return res; 5609 } 5610 5611 private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 5612 int[] users = sUserManager.getUserIds(); 5613 int res = 0; 5614 for (int user : users) { 5615 int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user); 5616 if (resInner < 0) { 5617 res = resInner; 5618 } 5619 } 5620 return res; 5621 } 5622 5623 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 5624 PackageParser.Package changingLib) { 5625 if (file.path != null) { 5626 usesLibraryFiles.add(file.path); 5627 return; 5628 } 5629 PackageParser.Package p = mPackages.get(file.apk); 5630 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 5631 // If we are doing this while in the middle of updating a library apk, 5632 // then we need to make sure to use that new apk for determining the 5633 // dependencies here. (We haven't yet finished committing the new apk 5634 // to the package manager state.) 5635 if (p == null || p.packageName.equals(changingLib.packageName)) { 5636 p = changingLib; 5637 } 5638 } 5639 if (p != null) { 5640 usesLibraryFiles.addAll(p.getAllCodePaths()); 5641 } 5642 } 5643 5644 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 5645 PackageParser.Package changingLib) throws PackageManagerException { 5646 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 5647 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 5648 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 5649 for (int i=0; i<N; i++) { 5650 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 5651 if (file == null) { 5652 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 5653 "Package " + pkg.packageName + " requires unavailable shared library " 5654 + pkg.usesLibraries.get(i) + "; failing!"); 5655 } 5656 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5657 } 5658 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 5659 for (int i=0; i<N; i++) { 5660 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 5661 if (file == null) { 5662 Slog.w(TAG, "Package " + pkg.packageName 5663 + " desires unavailable shared library " 5664 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 5665 } else { 5666 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5667 } 5668 } 5669 N = usesLibraryFiles.size(); 5670 if (N > 0) { 5671 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 5672 } else { 5673 pkg.usesLibraryFiles = null; 5674 } 5675 } 5676 } 5677 5678 private static boolean hasString(List<String> list, List<String> which) { 5679 if (list == null) { 5680 return false; 5681 } 5682 for (int i=list.size()-1; i>=0; i--) { 5683 for (int j=which.size()-1; j>=0; j--) { 5684 if (which.get(j).equals(list.get(i))) { 5685 return true; 5686 } 5687 } 5688 } 5689 return false; 5690 } 5691 5692 private void updateAllSharedLibrariesLPw() { 5693 for (PackageParser.Package pkg : mPackages.values()) { 5694 try { 5695 updateSharedLibrariesLPw(pkg, null); 5696 } catch (PackageManagerException e) { 5697 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5698 } 5699 } 5700 } 5701 5702 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 5703 PackageParser.Package changingPkg) { 5704 ArrayList<PackageParser.Package> res = null; 5705 for (PackageParser.Package pkg : mPackages.values()) { 5706 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 5707 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 5708 if (res == null) { 5709 res = new ArrayList<PackageParser.Package>(); 5710 } 5711 res.add(pkg); 5712 try { 5713 updateSharedLibrariesLPw(pkg, changingPkg); 5714 } catch (PackageManagerException e) { 5715 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5716 } 5717 } 5718 } 5719 return res; 5720 } 5721 5722 /** 5723 * Derive the value of the {@code cpuAbiOverride} based on the provided 5724 * value and an optional stored value from the package settings. 5725 */ 5726 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 5727 String cpuAbiOverride = null; 5728 5729 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 5730 cpuAbiOverride = null; 5731 } else if (abiOverride != null) { 5732 cpuAbiOverride = abiOverride; 5733 } else if (settings != null) { 5734 cpuAbiOverride = settings.cpuAbiOverrideString; 5735 } 5736 5737 return cpuAbiOverride; 5738 } 5739 5740 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 5741 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5742 boolean success = false; 5743 try { 5744 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 5745 currentTime, user); 5746 success = true; 5747 return res; 5748 } finally { 5749 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5750 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 5751 } 5752 } 5753 } 5754 5755 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 5756 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5757 final File scanFile = new File(pkg.codePath); 5758 if (pkg.applicationInfo.getCodePath() == null || 5759 pkg.applicationInfo.getResourcePath() == null) { 5760 // Bail out. The resource and code paths haven't been set. 5761 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 5762 "Code and resource paths haven't been set correctly"); 5763 } 5764 5765 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5766 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 5767 } else { 5768 // Only allow system apps to be flagged as core apps. 5769 pkg.coreApp = false; 5770 } 5771 5772 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 5773 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5774 } 5775 5776 if (mCustomResolverComponentName != null && 5777 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 5778 setUpCustomResolverActivity(pkg); 5779 } 5780 5781 if (pkg.packageName.equals("android")) { 5782 synchronized (mPackages) { 5783 if (mAndroidApplication != null) { 5784 Slog.w(TAG, "*************************************************"); 5785 Slog.w(TAG, "Core android package being redefined. Skipping."); 5786 Slog.w(TAG, " file=" + scanFile); 5787 Slog.w(TAG, "*************************************************"); 5788 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5789 "Core android package being redefined. Skipping."); 5790 } 5791 5792 // Set up information for our fall-back user intent resolution activity. 5793 mPlatformPackage = pkg; 5794 pkg.mVersionCode = mSdkVersion; 5795 mAndroidApplication = pkg.applicationInfo; 5796 5797 if (!mResolverReplaced) { 5798 mResolveActivity.applicationInfo = mAndroidApplication; 5799 mResolveActivity.name = ResolverActivity.class.getName(); 5800 mResolveActivity.packageName = mAndroidApplication.packageName; 5801 mResolveActivity.processName = "system:ui"; 5802 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5803 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 5804 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 5805 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 5806 mResolveActivity.exported = true; 5807 mResolveActivity.enabled = true; 5808 mResolveInfo.activityInfo = mResolveActivity; 5809 mResolveInfo.priority = 0; 5810 mResolveInfo.preferredOrder = 0; 5811 mResolveInfo.match = 0; 5812 mResolveComponentName = new ComponentName( 5813 mAndroidApplication.packageName, mResolveActivity.name); 5814 } 5815 } 5816 } 5817 5818 if (DEBUG_PACKAGE_SCANNING) { 5819 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5820 Log.d(TAG, "Scanning package " + pkg.packageName); 5821 } 5822 5823 if (mPackages.containsKey(pkg.packageName) 5824 || mSharedLibraries.containsKey(pkg.packageName)) { 5825 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5826 "Application package " + pkg.packageName 5827 + " already installed. Skipping duplicate."); 5828 } 5829 5830 // If we're only installing presumed-existing packages, require that the 5831 // scanned APK is both already known and at the path previously established 5832 // for it. Previously unknown packages we pick up normally, but if we have an 5833 // a priori expectation about this package's install presence, enforce it. 5834 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 5835 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 5836 if (known != null) { 5837 if (DEBUG_PACKAGE_SCANNING) { 5838 Log.d(TAG, "Examining " + pkg.codePath 5839 + " and requiring known paths " + known.codePathString 5840 + " & " + known.resourcePathString); 5841 } 5842 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 5843 || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { 5844 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 5845 "Application package " + pkg.packageName 5846 + " found at " + pkg.applicationInfo.getCodePath() 5847 + " but expected at " + known.codePathString + "; ignoring."); 5848 } 5849 } 5850 } 5851 5852 // Initialize package source and resource directories 5853 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 5854 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 5855 5856 SharedUserSetting suid = null; 5857 PackageSetting pkgSetting = null; 5858 5859 if (!isSystemApp(pkg)) { 5860 // Only system apps can use these features. 5861 pkg.mOriginalPackages = null; 5862 pkg.mRealPackage = null; 5863 pkg.mAdoptPermissions = null; 5864 } 5865 5866 // writer 5867 synchronized (mPackages) { 5868 if (pkg.mSharedUserId != null) { 5869 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 5870 if (suid == null) { 5871 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5872 "Creating application package " + pkg.packageName 5873 + " for shared user failed"); 5874 } 5875 if (DEBUG_PACKAGE_SCANNING) { 5876 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5877 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 5878 + "): packages=" + suid.packages); 5879 } 5880 } 5881 5882 // Check if we are renaming from an original package name. 5883 PackageSetting origPackage = null; 5884 String realName = null; 5885 if (pkg.mOriginalPackages != null) { 5886 // This package may need to be renamed to a previously 5887 // installed name. Let's check on that... 5888 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 5889 if (pkg.mOriginalPackages.contains(renamed)) { 5890 // This package had originally been installed as the 5891 // original name, and we have already taken care of 5892 // transitioning to the new one. Just update the new 5893 // one to continue using the old name. 5894 realName = pkg.mRealPackage; 5895 if (!pkg.packageName.equals(renamed)) { 5896 // Callers into this function may have already taken 5897 // care of renaming the package; only do it here if 5898 // it is not already done. 5899 pkg.setPackageName(renamed); 5900 } 5901 5902 } else { 5903 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 5904 if ((origPackage = mSettings.peekPackageLPr( 5905 pkg.mOriginalPackages.get(i))) != null) { 5906 // We do have the package already installed under its 5907 // original name... should we use it? 5908 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 5909 // New package is not compatible with original. 5910 origPackage = null; 5911 continue; 5912 } else if (origPackage.sharedUser != null) { 5913 // Make sure uid is compatible between packages. 5914 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 5915 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 5916 + " to " + pkg.packageName + ": old uid " 5917 + origPackage.sharedUser.name 5918 + " differs from " + pkg.mSharedUserId); 5919 origPackage = null; 5920 continue; 5921 } 5922 } else { 5923 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 5924 + pkg.packageName + " to old name " + origPackage.name); 5925 } 5926 break; 5927 } 5928 } 5929 } 5930 } 5931 5932 if (mTransferedPackages.contains(pkg.packageName)) { 5933 Slog.w(TAG, "Package " + pkg.packageName 5934 + " was transferred to another, but its .apk remains"); 5935 } 5936 5937 // Just create the setting, don't add it yet. For already existing packages 5938 // the PkgSetting exists already and doesn't have to be created. 5939 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 5940 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 5941 pkg.applicationInfo.primaryCpuAbi, 5942 pkg.applicationInfo.secondaryCpuAbi, 5943 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 5944 user, false); 5945 if (pkgSetting == null) { 5946 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5947 "Creating application package " + pkg.packageName + " failed"); 5948 } 5949 5950 if (pkgSetting.origPackage != null) { 5951 // If we are first transitioning from an original package, 5952 // fix up the new package's name now. We need to do this after 5953 // looking up the package under its new name, so getPackageLP 5954 // can take care of fiddling things correctly. 5955 pkg.setPackageName(origPackage.name); 5956 5957 // File a report about this. 5958 String msg = "New package " + pkgSetting.realName 5959 + " renamed to replace old package " + pkgSetting.name; 5960 reportSettingsProblem(Log.WARN, msg); 5961 5962 // Make a note of it. 5963 mTransferedPackages.add(origPackage.name); 5964 5965 // No longer need to retain this. 5966 pkgSetting.origPackage = null; 5967 } 5968 5969 if (realName != null) { 5970 // Make a note of it. 5971 mTransferedPackages.add(pkg.packageName); 5972 } 5973 5974 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 5975 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 5976 } 5977 5978 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5979 // Check all shared libraries and map to their actual file path. 5980 // We only do this here for apps not on a system dir, because those 5981 // are the only ones that can fail an install due to this. We 5982 // will take care of the system apps by updating all of their 5983 // library paths after the scan is done. 5984 updateSharedLibrariesLPw(pkg, null); 5985 } 5986 5987 if (mFoundPolicyFile) { 5988 SELinuxMMAC.assignSeinfoValue(pkg); 5989 } 5990 5991 pkg.applicationInfo.uid = pkgSetting.appId; 5992 pkg.mExtras = pkgSetting; 5993 if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) { 5994 try { 5995 verifySignaturesLP(pkgSetting, pkg); 5996 // We just determined the app is signed correctly, so bring 5997 // over the latest parsed certs. 5998 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5999 } catch (PackageManagerException e) { 6000 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6001 throw e; 6002 } 6003 // The signature has changed, but this package is in the system 6004 // image... let's recover! 6005 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6006 // However... if this package is part of a shared user, but it 6007 // doesn't match the signature of the shared user, let's fail. 6008 // What this means is that you can't change the signatures 6009 // associated with an overall shared user, which doesn't seem all 6010 // that unreasonable. 6011 if (pkgSetting.sharedUser != null) { 6012 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6013 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 6014 throw new PackageManagerException( 6015 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 6016 "Signature mismatch for shared user : " 6017 + pkgSetting.sharedUser); 6018 } 6019 } 6020 // File a report about this. 6021 String msg = "System package " + pkg.packageName 6022 + " signature changed; retaining data."; 6023 reportSettingsProblem(Log.WARN, msg); 6024 } 6025 } else { 6026 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) { 6027 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6028 + pkg.packageName + " upgrade keys do not match the " 6029 + "previously installed version"); 6030 } else { 6031 // We just determined the app is signed correctly, so bring 6032 // over the latest parsed certs. 6033 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6034 } 6035 } 6036 // Verify that this new package doesn't have any content providers 6037 // that conflict with existing packages. Only do this if the 6038 // package isn't already installed, since we don't want to break 6039 // things that are installed. 6040 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 6041 final int N = pkg.providers.size(); 6042 int i; 6043 for (i=0; i<N; i++) { 6044 PackageParser.Provider p = pkg.providers.get(i); 6045 if (p.info.authority != null) { 6046 String names[] = p.info.authority.split(";"); 6047 for (int j = 0; j < names.length; j++) { 6048 if (mProvidersByAuthority.containsKey(names[j])) { 6049 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6050 final String otherPackageName = 6051 ((other != null && other.getComponentName() != null) ? 6052 other.getComponentName().getPackageName() : "?"); 6053 throw new PackageManagerException( 6054 INSTALL_FAILED_CONFLICTING_PROVIDER, 6055 "Can't install because provider name " + names[j] 6056 + " (in package " + pkg.applicationInfo.packageName 6057 + ") is already used by " + otherPackageName); 6058 } 6059 } 6060 } 6061 } 6062 } 6063 6064 if (pkg.mAdoptPermissions != null) { 6065 // This package wants to adopt ownership of permissions from 6066 // another package. 6067 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 6068 final String origName = pkg.mAdoptPermissions.get(i); 6069 final PackageSetting orig = mSettings.peekPackageLPr(origName); 6070 if (orig != null) { 6071 if (verifyPackageUpdateLPr(orig, pkg)) { 6072 Slog.i(TAG, "Adopting permissions from " + origName + " to " 6073 + pkg.packageName); 6074 mSettings.transferPermissionsLPw(origName, pkg.packageName); 6075 } 6076 } 6077 } 6078 } 6079 } 6080 6081 final String pkgName = pkg.packageName; 6082 6083 final long scanFileTime = scanFile.lastModified(); 6084 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 6085 pkg.applicationInfo.processName = fixProcessName( 6086 pkg.applicationInfo.packageName, 6087 pkg.applicationInfo.processName, 6088 pkg.applicationInfo.uid); 6089 6090 File dataPath; 6091 if (mPlatformPackage == pkg) { 6092 // The system package is special. 6093 dataPath = new File(Environment.getDataDirectory(), "system"); 6094 6095 pkg.applicationInfo.dataDir = dataPath.getPath(); 6096 6097 } else { 6098 // This is a normal package, need to make its data directory. 6099 dataPath = PackageManager.getDataDirForUser(pkg.volumeUuid, pkg.packageName, 6100 UserHandle.USER_OWNER); 6101 6102 boolean uidError = false; 6103 if (dataPath.exists()) { 6104 int currentUid = 0; 6105 try { 6106 StructStat stat = Os.stat(dataPath.getPath()); 6107 currentUid = stat.st_uid; 6108 } catch (ErrnoException e) { 6109 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 6110 } 6111 6112 // If we have mismatched owners for the data path, we have a problem. 6113 if (currentUid != pkg.applicationInfo.uid) { 6114 boolean recovered = false; 6115 if (currentUid == 0) { 6116 // The directory somehow became owned by root. Wow. 6117 // This is probably because the system was stopped while 6118 // installd was in the middle of messing with its libs 6119 // directory. Ask installd to fix that. 6120 int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName, 6121 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 6122 if (ret >= 0) { 6123 recovered = true; 6124 String msg = "Package " + pkg.packageName 6125 + " unexpectedly changed to uid 0; recovered to " + 6126 + pkg.applicationInfo.uid; 6127 reportSettingsProblem(Log.WARN, msg); 6128 } 6129 } 6130 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6131 || (scanFlags&SCAN_BOOTING) != 0)) { 6132 // If this is a system app, we can at least delete its 6133 // current data so the application will still work. 6134 int ret = removeDataDirsLI(pkg.volumeUuid, pkgName); 6135 if (ret >= 0) { 6136 // TODO: Kill the processes first 6137 // Old data gone! 6138 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6139 ? "System package " : "Third party package "; 6140 String msg = prefix + pkg.packageName 6141 + " has changed from uid: " 6142 + currentUid + " to " 6143 + pkg.applicationInfo.uid + "; old data erased"; 6144 reportSettingsProblem(Log.WARN, msg); 6145 recovered = true; 6146 6147 // And now re-install the app. 6148 ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6149 pkg.applicationInfo.seinfo); 6150 if (ret == -1) { 6151 // Ack should not happen! 6152 msg = prefix + pkg.packageName 6153 + " could not have data directory re-created after delete."; 6154 reportSettingsProblem(Log.WARN, msg); 6155 throw new PackageManagerException( 6156 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 6157 } 6158 } 6159 if (!recovered) { 6160 mHasSystemUidErrors = true; 6161 } 6162 } else if (!recovered) { 6163 // If we allow this install to proceed, we will be broken. 6164 // Abort, abort! 6165 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 6166 "scanPackageLI"); 6167 } 6168 if (!recovered) { 6169 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 6170 + pkg.applicationInfo.uid + "/fs_" 6171 + currentUid; 6172 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 6173 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 6174 String msg = "Package " + pkg.packageName 6175 + " has mismatched uid: " 6176 + currentUid + " on disk, " 6177 + pkg.applicationInfo.uid + " in settings"; 6178 // writer 6179 synchronized (mPackages) { 6180 mSettings.mReadMessages.append(msg); 6181 mSettings.mReadMessages.append('\n'); 6182 uidError = true; 6183 if (!pkgSetting.uidError) { 6184 reportSettingsProblem(Log.ERROR, msg); 6185 } 6186 } 6187 } 6188 } 6189 pkg.applicationInfo.dataDir = dataPath.getPath(); 6190 if (mShouldRestoreconData) { 6191 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 6192 mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName, 6193 pkg.applicationInfo.seinfo, pkg.applicationInfo.uid); 6194 } 6195 } else { 6196 if (DEBUG_PACKAGE_SCANNING) { 6197 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6198 Log.v(TAG, "Want this data dir: " + dataPath); 6199 } 6200 //invoke installer to do the actual installation 6201 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6202 pkg.applicationInfo.seinfo); 6203 if (ret < 0) { 6204 // Error from installer 6205 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6206 "Unable to create data dirs [errorCode=" + ret + "]"); 6207 } 6208 6209 if (dataPath.exists()) { 6210 pkg.applicationInfo.dataDir = dataPath.getPath(); 6211 } else { 6212 Slog.w(TAG, "Unable to create data directory: " + dataPath); 6213 pkg.applicationInfo.dataDir = null; 6214 } 6215 } 6216 6217 pkgSetting.uidError = uidError; 6218 } 6219 6220 final String path = scanFile.getPath(); 6221 final String codePath = pkg.applicationInfo.getCodePath(); 6222 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 6223 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 6224 setBundledAppAbisAndRoots(pkg, pkgSetting); 6225 6226 // If we haven't found any native libraries for the app, check if it has 6227 // renderscript code. We'll need to force the app to 32 bit if it has 6228 // renderscript bitcode. 6229 if (pkg.applicationInfo.primaryCpuAbi == null 6230 && pkg.applicationInfo.secondaryCpuAbi == null 6231 && Build.SUPPORTED_64_BIT_ABIS.length > 0) { 6232 NativeLibraryHelper.Handle handle = null; 6233 try { 6234 handle = NativeLibraryHelper.Handle.create(scanFile); 6235 if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 6236 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6237 } 6238 } catch (IOException ioe) { 6239 Slog.w(TAG, "Error scanning system app : " + ioe); 6240 } finally { 6241 IoUtils.closeQuietly(handle); 6242 } 6243 } 6244 6245 setNativeLibraryPaths(pkg); 6246 } else { 6247 // TODO: We can probably be smarter about this stuff. For installed apps, 6248 // we can calculate this information at install time once and for all. For 6249 // system apps, we can probably assume that this information doesn't change 6250 // after the first boot scan. As things stand, we do lots of unnecessary work. 6251 6252 // Give ourselves some initial paths; we'll come back for another 6253 // pass once we've determined ABI below. 6254 setNativeLibraryPaths(pkg); 6255 6256 final boolean isAsec = pkg.isForwardLocked() || isExternal(pkg); 6257 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 6258 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 6259 6260 NativeLibraryHelper.Handle handle = null; 6261 try { 6262 handle = NativeLibraryHelper.Handle.create(scanFile); 6263 // TODO(multiArch): This can be null for apps that didn't go through the 6264 // usual installation process. We can calculate it again, like we 6265 // do during install time. 6266 // 6267 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 6268 // unnecessary. 6269 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 6270 6271 // Null out the abis so that they can be recalculated. 6272 pkg.applicationInfo.primaryCpuAbi = null; 6273 pkg.applicationInfo.secondaryCpuAbi = null; 6274 if (isMultiArch(pkg.applicationInfo)) { 6275 // Warn if we've set an abiOverride for multi-lib packages.. 6276 // By definition, we need to copy both 32 and 64 bit libraries for 6277 // such packages. 6278 if (pkg.cpuAbiOverride != null 6279 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 6280 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 6281 } 6282 6283 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 6284 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 6285 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 6286 if (isAsec) { 6287 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 6288 } else { 6289 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6290 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 6291 useIsaSpecificSubdirs); 6292 } 6293 } 6294 6295 maybeThrowExceptionForMultiArchCopy( 6296 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 6297 6298 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 6299 if (isAsec) { 6300 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 6301 } else { 6302 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6303 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 6304 useIsaSpecificSubdirs); 6305 } 6306 } 6307 6308 maybeThrowExceptionForMultiArchCopy( 6309 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 6310 6311 if (abi64 >= 0) { 6312 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 6313 } 6314 6315 if (abi32 >= 0) { 6316 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 6317 if (abi64 >= 0) { 6318 pkg.applicationInfo.secondaryCpuAbi = abi; 6319 } else { 6320 pkg.applicationInfo.primaryCpuAbi = abi; 6321 } 6322 } 6323 } else { 6324 String[] abiList = (cpuAbiOverride != null) ? 6325 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 6326 6327 // Enable gross and lame hacks for apps that are built with old 6328 // SDK tools. We must scan their APKs for renderscript bitcode and 6329 // not launch them if it's present. Don't bother checking on devices 6330 // that don't have 64 bit support. 6331 boolean needsRenderScriptOverride = false; 6332 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 6333 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 6334 abiList = Build.SUPPORTED_32_BIT_ABIS; 6335 needsRenderScriptOverride = true; 6336 } 6337 6338 final int copyRet; 6339 if (isAsec) { 6340 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 6341 } else { 6342 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 6343 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 6344 } 6345 6346 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 6347 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 6348 "Error unpackaging native libs for app, errorCode=" + copyRet); 6349 } 6350 6351 if (copyRet >= 0) { 6352 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 6353 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 6354 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 6355 } else if (needsRenderScriptOverride) { 6356 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 6357 } 6358 } 6359 } catch (IOException ioe) { 6360 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 6361 } finally { 6362 IoUtils.closeQuietly(handle); 6363 } 6364 6365 // Now that we've calculated the ABIs and determined if it's an internal app, 6366 // we will go ahead and populate the nativeLibraryPath. 6367 setNativeLibraryPaths(pkg); 6368 6369 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 6370 final int[] userIds = sUserManager.getUserIds(); 6371 synchronized (mInstallLock) { 6372 // Create a native library symlink only if we have native libraries 6373 // and if the native libraries are 32 bit libraries. We do not provide 6374 // this symlink for 64 bit libraries. 6375 if (pkg.applicationInfo.primaryCpuAbi != null && 6376 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 6377 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 6378 for (int userId : userIds) { 6379 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 6380 nativeLibPath, userId) < 0) { 6381 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 6382 "Failed linking native library dir (user=" + userId + ")"); 6383 } 6384 } 6385 } 6386 } 6387 } 6388 6389 // This is a special case for the "system" package, where the ABI is 6390 // dictated by the zygote configuration (and init.rc). We should keep track 6391 // of this ABI so that we can deal with "normal" applications that run under 6392 // the same UID correctly. 6393 if (mPlatformPackage == pkg) { 6394 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 6395 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 6396 } 6397 6398 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 6399 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 6400 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 6401 // Copy the derived override back to the parsed package, so that we can 6402 // update the package settings accordingly. 6403 pkg.cpuAbiOverride = cpuAbiOverride; 6404 6405 if (DEBUG_ABI_SELECTION) { 6406 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 6407 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 6408 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 6409 } 6410 6411 // Push the derived path down into PackageSettings so we know what to 6412 // clean up at uninstall time. 6413 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 6414 6415 if (DEBUG_ABI_SELECTION) { 6416 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 6417 " primary=" + pkg.applicationInfo.primaryCpuAbi + 6418 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 6419 } 6420 6421 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 6422 // We don't do this here during boot because we can do it all 6423 // at once after scanning all existing packages. 6424 // 6425 // We also do this *before* we perform dexopt on this package, so that 6426 // we can avoid redundant dexopts, and also to make sure we've got the 6427 // code and package path correct. 6428 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 6429 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); 6430 } 6431 6432 if ((scanFlags & SCAN_NO_DEX) == 0) { 6433 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, 6434 forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */); 6435 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6436 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 6437 } 6438 } 6439 if (mFactoryTest && pkg.requestedPermissions.contains( 6440 android.Manifest.permission.FACTORY_TEST)) { 6441 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 6442 } 6443 6444 ArrayList<PackageParser.Package> clientLibPkgs = null; 6445 6446 // writer 6447 synchronized (mPackages) { 6448 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6449 // Only system apps can add new shared libraries. 6450 if (pkg.libraryNames != null) { 6451 for (int i=0; i<pkg.libraryNames.size(); i++) { 6452 String name = pkg.libraryNames.get(i); 6453 boolean allowed = false; 6454 if (pkg.isUpdatedSystemApp()) { 6455 // New library entries can only be added through the 6456 // system image. This is important to get rid of a lot 6457 // of nasty edge cases: for example if we allowed a non- 6458 // system update of the app to add a library, then uninstalling 6459 // the update would make the library go away, and assumptions 6460 // we made such as through app install filtering would now 6461 // have allowed apps on the device which aren't compatible 6462 // with it. Better to just have the restriction here, be 6463 // conservative, and create many fewer cases that can negatively 6464 // impact the user experience. 6465 final PackageSetting sysPs = mSettings 6466 .getDisabledSystemPkgLPr(pkg.packageName); 6467 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 6468 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 6469 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 6470 allowed = true; 6471 allowed = true; 6472 break; 6473 } 6474 } 6475 } 6476 } else { 6477 allowed = true; 6478 } 6479 if (allowed) { 6480 if (!mSharedLibraries.containsKey(name)) { 6481 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 6482 } else if (!name.equals(pkg.packageName)) { 6483 Slog.w(TAG, "Package " + pkg.packageName + " library " 6484 + name + " already exists; skipping"); 6485 } 6486 } else { 6487 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 6488 + name + " that is not declared on system image; skipping"); 6489 } 6490 } 6491 if ((scanFlags&SCAN_BOOTING) == 0) { 6492 // If we are not booting, we need to update any applications 6493 // that are clients of our shared library. If we are booting, 6494 // this will all be done once the scan is complete. 6495 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 6496 } 6497 } 6498 } 6499 } 6500 6501 // We also need to dexopt any apps that are dependent on this library. Note that 6502 // if these fail, we should abort the install since installing the library will 6503 // result in some apps being broken. 6504 if (clientLibPkgs != null) { 6505 if ((scanFlags & SCAN_NO_DEX) == 0) { 6506 for (int i = 0; i < clientLibPkgs.size(); i++) { 6507 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6508 int result = mPackageDexOptimizer.performDexOpt(clientPkg, 6509 null /* instruction sets */, forceDex, 6510 (scanFlags & SCAN_DEFER_DEX) != 0, false); 6511 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6512 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 6513 "scanPackageLI failed to dexopt clientLibPkgs"); 6514 } 6515 } 6516 } 6517 } 6518 6519 // Also need to kill any apps that are dependent on the library. 6520 if (clientLibPkgs != null) { 6521 for (int i=0; i<clientLibPkgs.size(); i++) { 6522 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6523 killApplication(clientPkg.applicationInfo.packageName, 6524 clientPkg.applicationInfo.uid, "update lib"); 6525 } 6526 } 6527 6528 // writer 6529 synchronized (mPackages) { 6530 // We don't expect installation to fail beyond this point 6531 6532 // Add the new setting to mSettings 6533 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 6534 // Add the new setting to mPackages 6535 mPackages.put(pkg.applicationInfo.packageName, pkg); 6536 // Make sure we don't accidentally delete its data. 6537 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 6538 while (iter.hasNext()) { 6539 PackageCleanItem item = iter.next(); 6540 if (pkgName.equals(item.packageName)) { 6541 iter.remove(); 6542 } 6543 } 6544 6545 // Take care of first install / last update times. 6546 if (currentTime != 0) { 6547 if (pkgSetting.firstInstallTime == 0) { 6548 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 6549 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 6550 pkgSetting.lastUpdateTime = currentTime; 6551 } 6552 } else if (pkgSetting.firstInstallTime == 0) { 6553 // We need *something*. Take time time stamp of the file. 6554 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 6555 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 6556 if (scanFileTime != pkgSetting.timeStamp) { 6557 // A package on the system image has changed; consider this 6558 // to be an update. 6559 pkgSetting.lastUpdateTime = scanFileTime; 6560 } 6561 } 6562 6563 // Add the package's KeySets to the global KeySetManagerService 6564 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6565 try { 6566 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys); 6567 if (pkg.mKeySetMapping != null) { 6568 ksms.addDefinedKeySetsToPackageLPw(pkg.packageName, pkg.mKeySetMapping); 6569 if (pkg.mUpgradeKeySets != null) { 6570 ksms.addUpgradeKeySetsToPackageLPw(pkg.packageName, pkg.mUpgradeKeySets); 6571 } 6572 } 6573 } catch (NullPointerException e) { 6574 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 6575 } catch (IllegalArgumentException e) { 6576 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 6577 } 6578 6579 int N = pkg.providers.size(); 6580 StringBuilder r = null; 6581 int i; 6582 for (i=0; i<N; i++) { 6583 PackageParser.Provider p = pkg.providers.get(i); 6584 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 6585 p.info.processName, pkg.applicationInfo.uid); 6586 mProviders.addProvider(p); 6587 p.syncable = p.info.isSyncable; 6588 if (p.info.authority != null) { 6589 String names[] = p.info.authority.split(";"); 6590 p.info.authority = null; 6591 for (int j = 0; j < names.length; j++) { 6592 if (j == 1 && p.syncable) { 6593 // We only want the first authority for a provider to possibly be 6594 // syncable, so if we already added this provider using a different 6595 // authority clear the syncable flag. We copy the provider before 6596 // changing it because the mProviders object contains a reference 6597 // to a provider that we don't want to change. 6598 // Only do this for the second authority since the resulting provider 6599 // object can be the same for all future authorities for this provider. 6600 p = new PackageParser.Provider(p); 6601 p.syncable = false; 6602 } 6603 if (!mProvidersByAuthority.containsKey(names[j])) { 6604 mProvidersByAuthority.put(names[j], p); 6605 if (p.info.authority == null) { 6606 p.info.authority = names[j]; 6607 } else { 6608 p.info.authority = p.info.authority + ";" + names[j]; 6609 } 6610 if (DEBUG_PACKAGE_SCANNING) { 6611 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6612 Log.d(TAG, "Registered content provider: " + names[j] 6613 + ", className = " + p.info.name + ", isSyncable = " 6614 + p.info.isSyncable); 6615 } 6616 } else { 6617 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6618 Slog.w(TAG, "Skipping provider name " + names[j] + 6619 " (in package " + pkg.applicationInfo.packageName + 6620 "): name already used by " 6621 + ((other != null && other.getComponentName() != null) 6622 ? other.getComponentName().getPackageName() : "?")); 6623 } 6624 } 6625 } 6626 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6627 if (r == null) { 6628 r = new StringBuilder(256); 6629 } else { 6630 r.append(' '); 6631 } 6632 r.append(p.info.name); 6633 } 6634 } 6635 if (r != null) { 6636 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 6637 } 6638 6639 N = pkg.services.size(); 6640 r = null; 6641 for (i=0; i<N; i++) { 6642 PackageParser.Service s = pkg.services.get(i); 6643 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 6644 s.info.processName, pkg.applicationInfo.uid); 6645 mServices.addService(s); 6646 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6647 if (r == null) { 6648 r = new StringBuilder(256); 6649 } else { 6650 r.append(' '); 6651 } 6652 r.append(s.info.name); 6653 } 6654 } 6655 if (r != null) { 6656 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 6657 } 6658 6659 N = pkg.receivers.size(); 6660 r = null; 6661 for (i=0; i<N; i++) { 6662 PackageParser.Activity a = pkg.receivers.get(i); 6663 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6664 a.info.processName, pkg.applicationInfo.uid); 6665 mReceivers.addActivity(a, "receiver"); 6666 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6667 if (r == null) { 6668 r = new StringBuilder(256); 6669 } else { 6670 r.append(' '); 6671 } 6672 r.append(a.info.name); 6673 } 6674 } 6675 if (r != null) { 6676 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 6677 } 6678 6679 N = pkg.activities.size(); 6680 r = null; 6681 for (i=0; i<N; i++) { 6682 PackageParser.Activity a = pkg.activities.get(i); 6683 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6684 a.info.processName, pkg.applicationInfo.uid); 6685 mActivities.addActivity(a, "activity"); 6686 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6687 if (r == null) { 6688 r = new StringBuilder(256); 6689 } else { 6690 r.append(' '); 6691 } 6692 r.append(a.info.name); 6693 } 6694 } 6695 if (r != null) { 6696 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 6697 } 6698 6699 N = pkg.permissionGroups.size(); 6700 r = null; 6701 for (i=0; i<N; i++) { 6702 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 6703 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 6704 if (cur == null) { 6705 mPermissionGroups.put(pg.info.name, pg); 6706 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6707 if (r == null) { 6708 r = new StringBuilder(256); 6709 } else { 6710 r.append(' '); 6711 } 6712 r.append(pg.info.name); 6713 } 6714 } else { 6715 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 6716 + pg.info.packageName + " ignored: original from " 6717 + cur.info.packageName); 6718 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6719 if (r == null) { 6720 r = new StringBuilder(256); 6721 } else { 6722 r.append(' '); 6723 } 6724 r.append("DUP:"); 6725 r.append(pg.info.name); 6726 } 6727 } 6728 } 6729 if (r != null) { 6730 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 6731 } 6732 6733 N = pkg.permissions.size(); 6734 r = null; 6735 for (i=0; i<N; i++) { 6736 PackageParser.Permission p = pkg.permissions.get(i); 6737 6738 // Now that permission groups have a special meaning, we ignore permission 6739 // groups for legacy apps to prevent unexpected behavior. In particular, 6740 // permissions for one app being granted to someone just becuase they happen 6741 // to be in a group defined by another app (before this had no implications). 6742 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 6743 p.group = mPermissionGroups.get(p.info.group); 6744 // Warn for a permission in an unknown group. 6745 if (p.info.group != null && p.group == null) { 6746 Slog.w(TAG, "Permission " + p.info.name + " from package " 6747 + p.info.packageName + " in an unknown group " + p.info.group); 6748 } 6749 } 6750 6751 ArrayMap<String, BasePermission> permissionMap = 6752 p.tree ? mSettings.mPermissionTrees 6753 : mSettings.mPermissions; 6754 BasePermission bp = permissionMap.get(p.info.name); 6755 6756 // Allow system apps to redefine non-system permissions 6757 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 6758 final boolean currentOwnerIsSystem = (bp.perm != null 6759 && isSystemApp(bp.perm.owner)); 6760 if (isSystemApp(p.owner)) { 6761 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 6762 // It's a built-in permission and no owner, take ownership now 6763 bp.packageSetting = pkgSetting; 6764 bp.perm = p; 6765 bp.uid = pkg.applicationInfo.uid; 6766 bp.sourcePackage = p.info.packageName; 6767 } else if (!currentOwnerIsSystem) { 6768 String msg = "New decl " + p.owner + " of permission " 6769 + p.info.name + " is system; overriding " + bp.sourcePackage; 6770 reportSettingsProblem(Log.WARN, msg); 6771 bp = null; 6772 } 6773 } 6774 } 6775 6776 if (bp == null) { 6777 bp = new BasePermission(p.info.name, p.info.packageName, 6778 BasePermission.TYPE_NORMAL); 6779 permissionMap.put(p.info.name, bp); 6780 } 6781 6782 if (bp.perm == null) { 6783 if (bp.sourcePackage == null 6784 || bp.sourcePackage.equals(p.info.packageName)) { 6785 BasePermission tree = findPermissionTreeLP(p.info.name); 6786 if (tree == null 6787 || tree.sourcePackage.equals(p.info.packageName)) { 6788 bp.packageSetting = pkgSetting; 6789 bp.perm = p; 6790 bp.uid = pkg.applicationInfo.uid; 6791 bp.sourcePackage = p.info.packageName; 6792 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6793 if (r == null) { 6794 r = new StringBuilder(256); 6795 } else { 6796 r.append(' '); 6797 } 6798 r.append(p.info.name); 6799 } 6800 } else { 6801 Slog.w(TAG, "Permission " + p.info.name + " from package " 6802 + p.info.packageName + " ignored: base tree " 6803 + tree.name + " is from package " 6804 + tree.sourcePackage); 6805 } 6806 } else { 6807 Slog.w(TAG, "Permission " + p.info.name + " from package " 6808 + p.info.packageName + " ignored: original from " 6809 + bp.sourcePackage); 6810 } 6811 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6812 if (r == null) { 6813 r = new StringBuilder(256); 6814 } else { 6815 r.append(' '); 6816 } 6817 r.append("DUP:"); 6818 r.append(p.info.name); 6819 } 6820 if (bp.perm == p) { 6821 bp.protectionLevel = p.info.protectionLevel; 6822 } 6823 } 6824 6825 if (r != null) { 6826 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 6827 } 6828 6829 N = pkg.instrumentation.size(); 6830 r = null; 6831 for (i=0; i<N; i++) { 6832 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6833 a.info.packageName = pkg.applicationInfo.packageName; 6834 a.info.sourceDir = pkg.applicationInfo.sourceDir; 6835 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 6836 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 6837 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 6838 a.info.dataDir = pkg.applicationInfo.dataDir; 6839 6840 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 6841 // need other information about the application, like the ABI and what not ? 6842 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 6843 mInstrumentation.put(a.getComponentName(), a); 6844 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6845 if (r == null) { 6846 r = new StringBuilder(256); 6847 } else { 6848 r.append(' '); 6849 } 6850 r.append(a.info.name); 6851 } 6852 } 6853 if (r != null) { 6854 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 6855 } 6856 6857 if (pkg.protectedBroadcasts != null) { 6858 N = pkg.protectedBroadcasts.size(); 6859 for (i=0; i<N; i++) { 6860 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 6861 } 6862 } 6863 6864 pkgSetting.setTimeStamp(scanFileTime); 6865 6866 // Create idmap files for pairs of (packages, overlay packages). 6867 // Note: "android", ie framework-res.apk, is handled by native layers. 6868 if (pkg.mOverlayTarget != null) { 6869 // This is an overlay package. 6870 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 6871 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 6872 mOverlays.put(pkg.mOverlayTarget, 6873 new ArrayMap<String, PackageParser.Package>()); 6874 } 6875 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 6876 map.put(pkg.packageName, pkg); 6877 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 6878 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 6879 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6880 "scanPackageLI failed to createIdmap"); 6881 } 6882 } 6883 } else if (mOverlays.containsKey(pkg.packageName) && 6884 !pkg.packageName.equals("android")) { 6885 // This is a regular package, with one or more known overlay packages. 6886 createIdmapsForPackageLI(pkg); 6887 } 6888 } 6889 6890 return pkg; 6891 } 6892 6893 /** 6894 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 6895 * i.e, so that all packages can be run inside a single process if required. 6896 * 6897 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 6898 * this function will either try and make the ABI for all packages in {@code packagesForUser} 6899 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 6900 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 6901 * updating a package that belongs to a shared user. 6902 * 6903 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 6904 * adds unnecessary complexity. 6905 */ 6906 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 6907 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { 6908 String requiredInstructionSet = null; 6909 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 6910 requiredInstructionSet = VMRuntime.getInstructionSet( 6911 scannedPackage.applicationInfo.primaryCpuAbi); 6912 } 6913 6914 PackageSetting requirer = null; 6915 for (PackageSetting ps : packagesForUser) { 6916 // If packagesForUser contains scannedPackage, we skip it. This will happen 6917 // when scannedPackage is an update of an existing package. Without this check, 6918 // we will never be able to change the ABI of any package belonging to a shared 6919 // user, even if it's compatible with other packages. 6920 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6921 if (ps.primaryCpuAbiString == null) { 6922 continue; 6923 } 6924 6925 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 6926 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 6927 // We have a mismatch between instruction sets (say arm vs arm64) warn about 6928 // this but there's not much we can do. 6929 String errorMessage = "Instruction set mismatch, " 6930 + ((requirer == null) ? "[caller]" : requirer) 6931 + " requires " + requiredInstructionSet + " whereas " + ps 6932 + " requires " + instructionSet; 6933 Slog.w(TAG, errorMessage); 6934 } 6935 6936 if (requiredInstructionSet == null) { 6937 requiredInstructionSet = instructionSet; 6938 requirer = ps; 6939 } 6940 } 6941 } 6942 6943 if (requiredInstructionSet != null) { 6944 String adjustedAbi; 6945 if (requirer != null) { 6946 // requirer != null implies that either scannedPackage was null or that scannedPackage 6947 // did not require an ABI, in which case we have to adjust scannedPackage to match 6948 // the ABI of the set (which is the same as requirer's ABI) 6949 adjustedAbi = requirer.primaryCpuAbiString; 6950 if (scannedPackage != null) { 6951 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 6952 } 6953 } else { 6954 // requirer == null implies that we're updating all ABIs in the set to 6955 // match scannedPackage. 6956 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 6957 } 6958 6959 for (PackageSetting ps : packagesForUser) { 6960 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6961 if (ps.primaryCpuAbiString != null) { 6962 continue; 6963 } 6964 6965 ps.primaryCpuAbiString = adjustedAbi; 6966 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 6967 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 6968 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 6969 6970 int result = mPackageDexOptimizer.performDexOpt(ps.pkg, 6971 null /* instruction sets */, forceDexOpt, deferDexOpt, true); 6972 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6973 ps.primaryCpuAbiString = null; 6974 ps.pkg.applicationInfo.primaryCpuAbi = null; 6975 return; 6976 } else { 6977 mInstaller.rmdex(ps.codePathString, 6978 getDexCodeInstructionSet(getPreferredInstructionSet())); 6979 } 6980 } 6981 } 6982 } 6983 } 6984 } 6985 6986 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 6987 synchronized (mPackages) { 6988 mResolverReplaced = true; 6989 // Set up information for custom user intent resolution activity. 6990 mResolveActivity.applicationInfo = pkg.applicationInfo; 6991 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 6992 mResolveActivity.packageName = pkg.applicationInfo.packageName; 6993 mResolveActivity.processName = pkg.applicationInfo.packageName; 6994 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6995 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 6996 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 6997 mResolveActivity.theme = 0; 6998 mResolveActivity.exported = true; 6999 mResolveActivity.enabled = true; 7000 mResolveInfo.activityInfo = mResolveActivity; 7001 mResolveInfo.priority = 0; 7002 mResolveInfo.preferredOrder = 0; 7003 mResolveInfo.match = 0; 7004 mResolveComponentName = mCustomResolverComponentName; 7005 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 7006 mResolveComponentName); 7007 } 7008 } 7009 7010 private static String calculateBundledApkRoot(final String codePathString) { 7011 final File codePath = new File(codePathString); 7012 final File codeRoot; 7013 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 7014 codeRoot = Environment.getRootDirectory(); 7015 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 7016 codeRoot = Environment.getOemDirectory(); 7017 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 7018 codeRoot = Environment.getVendorDirectory(); 7019 } else { 7020 // Unrecognized code path; take its top real segment as the apk root: 7021 // e.g. /something/app/blah.apk => /something 7022 try { 7023 File f = codePath.getCanonicalFile(); 7024 File parent = f.getParentFile(); // non-null because codePath is a file 7025 File tmp; 7026 while ((tmp = parent.getParentFile()) != null) { 7027 f = parent; 7028 parent = tmp; 7029 } 7030 codeRoot = f; 7031 Slog.w(TAG, "Unrecognized code path " 7032 + codePath + " - using " + codeRoot); 7033 } catch (IOException e) { 7034 // Can't canonicalize the code path -- shenanigans? 7035 Slog.w(TAG, "Can't canonicalize code path " + codePath); 7036 return Environment.getRootDirectory().getPath(); 7037 } 7038 } 7039 return codeRoot.getPath(); 7040 } 7041 7042 /** 7043 * Derive and set the location of native libraries for the given package, 7044 * which varies depending on where and how the package was installed. 7045 */ 7046 private void setNativeLibraryPaths(PackageParser.Package pkg) { 7047 final ApplicationInfo info = pkg.applicationInfo; 7048 final String codePath = pkg.codePath; 7049 final File codeFile = new File(codePath); 7050 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 7051 final boolean asecApp = info.isForwardLocked() || isExternal(info); 7052 7053 info.nativeLibraryRootDir = null; 7054 info.nativeLibraryRootRequiresIsa = false; 7055 info.nativeLibraryDir = null; 7056 info.secondaryNativeLibraryDir = null; 7057 7058 if (isApkFile(codeFile)) { 7059 // Monolithic install 7060 if (bundledApp) { 7061 // If "/system/lib64/apkname" exists, assume that is the per-package 7062 // native library directory to use; otherwise use "/system/lib/apkname". 7063 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 7064 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 7065 getPrimaryInstructionSet(info)); 7066 7067 // This is a bundled system app so choose the path based on the ABI. 7068 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 7069 // is just the default path. 7070 final String apkName = deriveCodePathName(codePath); 7071 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 7072 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 7073 apkName).getAbsolutePath(); 7074 7075 if (info.secondaryCpuAbi != null) { 7076 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 7077 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 7078 secondaryLibDir, apkName).getAbsolutePath(); 7079 } 7080 } else if (asecApp) { 7081 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 7082 .getAbsolutePath(); 7083 } else { 7084 final String apkName = deriveCodePathName(codePath); 7085 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 7086 .getAbsolutePath(); 7087 } 7088 7089 info.nativeLibraryRootRequiresIsa = false; 7090 info.nativeLibraryDir = info.nativeLibraryRootDir; 7091 } else { 7092 // Cluster install 7093 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 7094 info.nativeLibraryRootRequiresIsa = true; 7095 7096 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 7097 getPrimaryInstructionSet(info)).getAbsolutePath(); 7098 7099 if (info.secondaryCpuAbi != null) { 7100 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 7101 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 7102 } 7103 } 7104 } 7105 7106 /** 7107 * Calculate the abis and roots for a bundled app. These can uniquely 7108 * be determined from the contents of the system partition, i.e whether 7109 * it contains 64 or 32 bit shared libraries etc. We do not validate any 7110 * of this information, and instead assume that the system was built 7111 * sensibly. 7112 */ 7113 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 7114 PackageSetting pkgSetting) { 7115 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 7116 7117 // If "/system/lib64/apkname" exists, assume that is the per-package 7118 // native library directory to use; otherwise use "/system/lib/apkname". 7119 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 7120 setBundledAppAbi(pkg, apkRoot, apkName); 7121 // pkgSetting might be null during rescan following uninstall of updates 7122 // to a bundled app, so accommodate that possibility. The settings in 7123 // that case will be established later from the parsed package. 7124 // 7125 // If the settings aren't null, sync them up with what we've just derived. 7126 // note that apkRoot isn't stored in the package settings. 7127 if (pkgSetting != null) { 7128 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7129 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7130 } 7131 } 7132 7133 /** 7134 * Deduces the ABI of a bundled app and sets the relevant fields on the 7135 * parsed pkg object. 7136 * 7137 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 7138 * under which system libraries are installed. 7139 * @param apkName the name of the installed package. 7140 */ 7141 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 7142 final File codeFile = new File(pkg.codePath); 7143 7144 final boolean has64BitLibs; 7145 final boolean has32BitLibs; 7146 if (isApkFile(codeFile)) { 7147 // Monolithic install 7148 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 7149 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 7150 } else { 7151 // Cluster install 7152 final File rootDir = new File(codeFile, LIB_DIR_NAME); 7153 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 7154 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 7155 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 7156 has64BitLibs = (new File(rootDir, isa)).exists(); 7157 } else { 7158 has64BitLibs = false; 7159 } 7160 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 7161 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 7162 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 7163 has32BitLibs = (new File(rootDir, isa)).exists(); 7164 } else { 7165 has32BitLibs = false; 7166 } 7167 } 7168 7169 if (has64BitLibs && !has32BitLibs) { 7170 // The package has 64 bit libs, but not 32 bit libs. Its primary 7171 // ABI should be 64 bit. We can safely assume here that the bundled 7172 // native libraries correspond to the most preferred ABI in the list. 7173 7174 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7175 pkg.applicationInfo.secondaryCpuAbi = null; 7176 } else if (has32BitLibs && !has64BitLibs) { 7177 // The package has 32 bit libs but not 64 bit libs. Its primary 7178 // ABI should be 32 bit. 7179 7180 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7181 pkg.applicationInfo.secondaryCpuAbi = null; 7182 } else if (has32BitLibs && has64BitLibs) { 7183 // The application has both 64 and 32 bit bundled libraries. We check 7184 // here that the app declares multiArch support, and warn if it doesn't. 7185 // 7186 // We will be lenient here and record both ABIs. The primary will be the 7187 // ABI that's higher on the list, i.e, a device that's configured to prefer 7188 // 64 bit apps will see a 64 bit primary ABI, 7189 7190 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 7191 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 7192 } 7193 7194 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 7195 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7196 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7197 } else { 7198 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7199 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7200 } 7201 } else { 7202 pkg.applicationInfo.primaryCpuAbi = null; 7203 pkg.applicationInfo.secondaryCpuAbi = null; 7204 } 7205 } 7206 7207 private void killApplication(String pkgName, int appId, String reason) { 7208 // Request the ActivityManager to kill the process(only for existing packages) 7209 // so that we do not end up in a confused state while the user is still using the older 7210 // version of the application while the new one gets installed. 7211 IActivityManager am = ActivityManagerNative.getDefault(); 7212 if (am != null) { 7213 try { 7214 am.killApplicationWithAppId(pkgName, appId, reason); 7215 } catch (RemoteException e) { 7216 } 7217 } 7218 } 7219 7220 void removePackageLI(PackageSetting ps, boolean chatty) { 7221 if (DEBUG_INSTALL) { 7222 if (chatty) 7223 Log.d(TAG, "Removing package " + ps.name); 7224 } 7225 7226 // writer 7227 synchronized (mPackages) { 7228 mPackages.remove(ps.name); 7229 final PackageParser.Package pkg = ps.pkg; 7230 if (pkg != null) { 7231 cleanPackageDataStructuresLILPw(pkg, chatty); 7232 } 7233 } 7234 } 7235 7236 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 7237 if (DEBUG_INSTALL) { 7238 if (chatty) 7239 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 7240 } 7241 7242 // writer 7243 synchronized (mPackages) { 7244 mPackages.remove(pkg.applicationInfo.packageName); 7245 cleanPackageDataStructuresLILPw(pkg, chatty); 7246 } 7247 } 7248 7249 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 7250 int N = pkg.providers.size(); 7251 StringBuilder r = null; 7252 int i; 7253 for (i=0; i<N; i++) { 7254 PackageParser.Provider p = pkg.providers.get(i); 7255 mProviders.removeProvider(p); 7256 if (p.info.authority == null) { 7257 7258 /* There was another ContentProvider with this authority when 7259 * this app was installed so this authority is null, 7260 * Ignore it as we don't have to unregister the provider. 7261 */ 7262 continue; 7263 } 7264 String names[] = p.info.authority.split(";"); 7265 for (int j = 0; j < names.length; j++) { 7266 if (mProvidersByAuthority.get(names[j]) == p) { 7267 mProvidersByAuthority.remove(names[j]); 7268 if (DEBUG_REMOVE) { 7269 if (chatty) 7270 Log.d(TAG, "Unregistered content provider: " + names[j] 7271 + ", className = " + p.info.name + ", isSyncable = " 7272 + p.info.isSyncable); 7273 } 7274 } 7275 } 7276 if (DEBUG_REMOVE && chatty) { 7277 if (r == null) { 7278 r = new StringBuilder(256); 7279 } else { 7280 r.append(' '); 7281 } 7282 r.append(p.info.name); 7283 } 7284 } 7285 if (r != null) { 7286 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 7287 } 7288 7289 N = pkg.services.size(); 7290 r = null; 7291 for (i=0; i<N; i++) { 7292 PackageParser.Service s = pkg.services.get(i); 7293 mServices.removeService(s); 7294 if (chatty) { 7295 if (r == null) { 7296 r = new StringBuilder(256); 7297 } else { 7298 r.append(' '); 7299 } 7300 r.append(s.info.name); 7301 } 7302 } 7303 if (r != null) { 7304 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 7305 } 7306 7307 N = pkg.receivers.size(); 7308 r = null; 7309 for (i=0; i<N; i++) { 7310 PackageParser.Activity a = pkg.receivers.get(i); 7311 mReceivers.removeActivity(a, "receiver"); 7312 if (DEBUG_REMOVE && chatty) { 7313 if (r == null) { 7314 r = new StringBuilder(256); 7315 } else { 7316 r.append(' '); 7317 } 7318 r.append(a.info.name); 7319 } 7320 } 7321 if (r != null) { 7322 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 7323 } 7324 7325 N = pkg.activities.size(); 7326 r = null; 7327 for (i=0; i<N; i++) { 7328 PackageParser.Activity a = pkg.activities.get(i); 7329 mActivities.removeActivity(a, "activity"); 7330 if (DEBUG_REMOVE && chatty) { 7331 if (r == null) { 7332 r = new StringBuilder(256); 7333 } else { 7334 r.append(' '); 7335 } 7336 r.append(a.info.name); 7337 } 7338 } 7339 if (r != null) { 7340 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 7341 } 7342 7343 N = pkg.permissions.size(); 7344 r = null; 7345 for (i=0; i<N; i++) { 7346 PackageParser.Permission p = pkg.permissions.get(i); 7347 BasePermission bp = mSettings.mPermissions.get(p.info.name); 7348 if (bp == null) { 7349 bp = mSettings.mPermissionTrees.get(p.info.name); 7350 } 7351 if (bp != null && bp.perm == p) { 7352 bp.perm = null; 7353 if (DEBUG_REMOVE && chatty) { 7354 if (r == null) { 7355 r = new StringBuilder(256); 7356 } else { 7357 r.append(' '); 7358 } 7359 r.append(p.info.name); 7360 } 7361 } 7362 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7363 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 7364 if (appOpPerms != null) { 7365 appOpPerms.remove(pkg.packageName); 7366 } 7367 } 7368 } 7369 if (r != null) { 7370 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7371 } 7372 7373 N = pkg.requestedPermissions.size(); 7374 r = null; 7375 for (i=0; i<N; i++) { 7376 String perm = pkg.requestedPermissions.get(i); 7377 BasePermission bp = mSettings.mPermissions.get(perm); 7378 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7379 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 7380 if (appOpPerms != null) { 7381 appOpPerms.remove(pkg.packageName); 7382 if (appOpPerms.isEmpty()) { 7383 mAppOpPermissionPackages.remove(perm); 7384 } 7385 } 7386 } 7387 } 7388 if (r != null) { 7389 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7390 } 7391 7392 N = pkg.instrumentation.size(); 7393 r = null; 7394 for (i=0; i<N; i++) { 7395 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 7396 mInstrumentation.remove(a.getComponentName()); 7397 if (DEBUG_REMOVE && chatty) { 7398 if (r == null) { 7399 r = new StringBuilder(256); 7400 } else { 7401 r.append(' '); 7402 } 7403 r.append(a.info.name); 7404 } 7405 } 7406 if (r != null) { 7407 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 7408 } 7409 7410 r = null; 7411 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7412 // Only system apps can hold shared libraries. 7413 if (pkg.libraryNames != null) { 7414 for (i=0; i<pkg.libraryNames.size(); i++) { 7415 String name = pkg.libraryNames.get(i); 7416 SharedLibraryEntry cur = mSharedLibraries.get(name); 7417 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 7418 mSharedLibraries.remove(name); 7419 if (DEBUG_REMOVE && chatty) { 7420 if (r == null) { 7421 r = new StringBuilder(256); 7422 } else { 7423 r.append(' '); 7424 } 7425 r.append(name); 7426 } 7427 } 7428 } 7429 } 7430 } 7431 if (r != null) { 7432 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 7433 } 7434 } 7435 7436 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 7437 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 7438 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 7439 return true; 7440 } 7441 } 7442 return false; 7443 } 7444 7445 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 7446 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 7447 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 7448 7449 private void updatePermissionsLPw(String changingPkg, 7450 PackageParser.Package pkgInfo, int flags) { 7451 // Make sure there are no dangling permission trees. 7452 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 7453 while (it.hasNext()) { 7454 final BasePermission bp = it.next(); 7455 if (bp.packageSetting == null) { 7456 // We may not yet have parsed the package, so just see if 7457 // we still know about its settings. 7458 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7459 } 7460 if (bp.packageSetting == null) { 7461 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 7462 + " from package " + bp.sourcePackage); 7463 it.remove(); 7464 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7465 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7466 Slog.i(TAG, "Removing old permission tree: " + bp.name 7467 + " from package " + bp.sourcePackage); 7468 flags |= UPDATE_PERMISSIONS_ALL; 7469 it.remove(); 7470 } 7471 } 7472 } 7473 7474 // Make sure all dynamic permissions have been assigned to a package, 7475 // and make sure there are no dangling permissions. 7476 it = mSettings.mPermissions.values().iterator(); 7477 while (it.hasNext()) { 7478 final BasePermission bp = it.next(); 7479 if (bp.type == BasePermission.TYPE_DYNAMIC) { 7480 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 7481 + bp.name + " pkg=" + bp.sourcePackage 7482 + " info=" + bp.pendingInfo); 7483 if (bp.packageSetting == null && bp.pendingInfo != null) { 7484 final BasePermission tree = findPermissionTreeLP(bp.name); 7485 if (tree != null && tree.perm != null) { 7486 bp.packageSetting = tree.packageSetting; 7487 bp.perm = new PackageParser.Permission(tree.perm.owner, 7488 new PermissionInfo(bp.pendingInfo)); 7489 bp.perm.info.packageName = tree.perm.info.packageName; 7490 bp.perm.info.name = bp.name; 7491 bp.uid = tree.uid; 7492 } 7493 } 7494 } 7495 if (bp.packageSetting == null) { 7496 // We may not yet have parsed the package, so just see if 7497 // we still know about its settings. 7498 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7499 } 7500 if (bp.packageSetting == null) { 7501 Slog.w(TAG, "Removing dangling permission: " + bp.name 7502 + " from package " + bp.sourcePackage); 7503 it.remove(); 7504 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7505 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7506 Slog.i(TAG, "Removing old permission: " + bp.name 7507 + " from package " + bp.sourcePackage); 7508 flags |= UPDATE_PERMISSIONS_ALL; 7509 it.remove(); 7510 } 7511 } 7512 } 7513 7514 // Now update the permissions for all packages, in particular 7515 // replace the granted permissions of the system packages. 7516 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 7517 for (PackageParser.Package pkg : mPackages.values()) { 7518 if (pkg != pkgInfo) { 7519 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0, 7520 changingPkg); 7521 } 7522 } 7523 } 7524 7525 if (pkgInfo != null) { 7526 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg); 7527 } 7528 } 7529 7530 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 7531 String packageOfInterest) { 7532 // IMPORTANT: There are two types of permissions: install and runtime. 7533 // Install time permissions are granted when the app is installed to 7534 // all device users and users added in the future. Runtime permissions 7535 // are granted at runtime explicitly to specific users. Normal and signature 7536 // protected permissions are install time permissions. Dangerous permissions 7537 // are install permissions if the app's target SDK is Lollipop MR1 or older, 7538 // otherwise they are runtime permissions. This function does not manage 7539 // runtime permissions except for the case an app targeting Lollipop MR1 7540 // being upgraded to target a newer SDK, in which case dangerous permissions 7541 // are transformed from install time to runtime ones. 7542 7543 final PackageSetting ps = (PackageSetting) pkg.mExtras; 7544 if (ps == null) { 7545 return; 7546 } 7547 7548 PermissionsState permissionsState = ps.getPermissionsState(); 7549 PermissionsState origPermissions = permissionsState; 7550 7551 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 7552 7553 int[] upgradeUserIds = PermissionsState.USERS_NONE; 7554 int[] changedRuntimePermissionUserIds = PermissionsState.USERS_NONE; 7555 7556 boolean changedInstallPermission = false; 7557 7558 if (replace) { 7559 ps.installPermissionsFixed = false; 7560 if (!ps.isSharedUser()) { 7561 origPermissions = new PermissionsState(permissionsState); 7562 permissionsState.reset(); 7563 } 7564 } 7565 7566 permissionsState.setGlobalGids(mGlobalGids); 7567 7568 final int N = pkg.requestedPermissions.size(); 7569 for (int i=0; i<N; i++) { 7570 final String name = pkg.requestedPermissions.get(i); 7571 final BasePermission bp = mSettings.mPermissions.get(name); 7572 7573 if (DEBUG_INSTALL) { 7574 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 7575 } 7576 7577 if (bp == null || bp.packageSetting == null) { 7578 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7579 Slog.w(TAG, "Unknown permission " + name 7580 + " in package " + pkg.packageName); 7581 } 7582 continue; 7583 } 7584 7585 final String perm = bp.name; 7586 boolean allowedSig = false; 7587 int grant = GRANT_DENIED; 7588 7589 // Keep track of app op permissions. 7590 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7591 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 7592 if (pkgs == null) { 7593 pkgs = new ArraySet<>(); 7594 mAppOpPermissionPackages.put(bp.name, pkgs); 7595 } 7596 pkgs.add(pkg.packageName); 7597 } 7598 7599 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 7600 switch (level) { 7601 case PermissionInfo.PROTECTION_NORMAL: { 7602 // For all apps normal permissions are install time ones. 7603 grant = GRANT_INSTALL; 7604 } break; 7605 7606 case PermissionInfo.PROTECTION_DANGEROUS: { 7607 if (!RUNTIME_PERMISSIONS_ENABLED 7608 || pkg.applicationInfo.targetSdkVersion 7609 <= Build.VERSION_CODES.LOLLIPOP_MR1) { 7610 // For legacy apps dangerous permissions are install time ones. 7611 grant = GRANT_INSTALL; 7612 } else if (ps.isSystem()) { 7613 final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds(); 7614 if (origPermissions.hasInstallPermission(bp.name)) { 7615 // If a system app had an install permission, then the app was 7616 // upgraded and we grant the permissions as runtime to all users. 7617 grant = GRANT_UPGRADE; 7618 upgradeUserIds = currentUserIds; 7619 } else if (!Arrays.equals(updatedUserIds, currentUserIds)) { 7620 // If users changed since the last permissions update for a 7621 // system app, we grant the permission as runtime to the new users. 7622 grant = GRANT_UPGRADE; 7623 upgradeUserIds = currentUserIds; 7624 for (int userId : updatedUserIds) { 7625 upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId); 7626 } 7627 } else { 7628 // Otherwise, we grant the permission as runtime if the app 7629 // already had it, i.e. we preserve runtime permissions. 7630 grant = GRANT_RUNTIME; 7631 } 7632 } else if (origPermissions.hasInstallPermission(bp.name)) { 7633 // For legacy apps that became modern, install becomes runtime. 7634 grant = GRANT_UPGRADE; 7635 upgradeUserIds = currentUserIds; 7636 } else if (replace) { 7637 // For upgraded modern apps keep runtime permissions unchanged. 7638 grant = GRANT_RUNTIME; 7639 } 7640 } break; 7641 7642 case PermissionInfo.PROTECTION_SIGNATURE: { 7643 // For all apps signature permissions are install time ones. 7644 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 7645 if (allowedSig) { 7646 grant = GRANT_INSTALL; 7647 } 7648 } break; 7649 } 7650 7651 if (DEBUG_INSTALL) { 7652 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 7653 } 7654 7655 if (grant != GRANT_DENIED) { 7656 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 7657 // If this is an existing, non-system package, then 7658 // we can't add any new permissions to it. 7659 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 7660 // Except... if this is a permission that was added 7661 // to the platform (note: need to only do this when 7662 // updating the platform). 7663 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 7664 grant = GRANT_DENIED; 7665 } 7666 } 7667 } 7668 7669 switch (grant) { 7670 case GRANT_INSTALL: { 7671 // Grant an install permission. 7672 if (permissionsState.grantInstallPermission(bp) != 7673 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7674 changedInstallPermission = true; 7675 } 7676 } break; 7677 7678 case GRANT_RUNTIME: { 7679 // Grant previously granted runtime permissions. 7680 for (int userId : UserManagerService.getInstance().getUserIds()) { 7681 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 7682 if (permissionsState.grantRuntimePermission(bp, userId) == 7683 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7684 // If we cannot put the permission as it was, we have to write. 7685 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7686 changedRuntimePermissionUserIds, userId); 7687 } 7688 } 7689 } 7690 } break; 7691 7692 case GRANT_UPGRADE: { 7693 // Grant runtime permissions for a previously held install permission. 7694 permissionsState.revokeInstallPermission(bp); 7695 for (int userId : upgradeUserIds) { 7696 if (permissionsState.grantRuntimePermission(bp, userId) != 7697 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7698 // If we granted the permission, we have to write. 7699 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7700 changedRuntimePermissionUserIds, userId); 7701 } 7702 } 7703 } break; 7704 7705 default: { 7706 if (packageOfInterest == null 7707 || packageOfInterest.equals(pkg.packageName)) { 7708 Slog.w(TAG, "Not granting permission " + perm 7709 + " to package " + pkg.packageName 7710 + " because it was previously installed without"); 7711 } 7712 } break; 7713 } 7714 } else { 7715 if (permissionsState.revokeInstallPermission(bp) != 7716 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7717 changedInstallPermission = true; 7718 Slog.i(TAG, "Un-granting permission " + perm 7719 + " from package " + pkg.packageName 7720 + " (protectionLevel=" + bp.protectionLevel 7721 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7722 + ")"); 7723 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 7724 // Don't print warning for app op permissions, since it is fine for them 7725 // not to be granted, there is a UI for the user to decide. 7726 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7727 Slog.w(TAG, "Not granting permission " + perm 7728 + " to package " + pkg.packageName 7729 + " (protectionLevel=" + bp.protectionLevel 7730 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7731 + ")"); 7732 } 7733 } 7734 } 7735 } 7736 7737 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 7738 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 7739 // This is the first that we have heard about this package, so the 7740 // permissions we have now selected are fixed until explicitly 7741 // changed. 7742 ps.installPermissionsFixed = true; 7743 } 7744 7745 ps.setPermissionsUpdatedForUserIds(currentUserIds); 7746 7747 // Persist the runtime permissions state for users with changes. 7748 if (RUNTIME_PERMISSIONS_ENABLED) { 7749 for (int userId : changedRuntimePermissionUserIds) { 7750 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 7751 } 7752 } 7753 } 7754 7755 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 7756 boolean allowed = false; 7757 final int NP = PackageParser.NEW_PERMISSIONS.length; 7758 for (int ip=0; ip<NP; ip++) { 7759 final PackageParser.NewPermissionInfo npi 7760 = PackageParser.NEW_PERMISSIONS[ip]; 7761 if (npi.name.equals(perm) 7762 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 7763 allowed = true; 7764 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 7765 + pkg.packageName); 7766 break; 7767 } 7768 } 7769 return allowed; 7770 } 7771 7772 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 7773 BasePermission bp, PermissionsState origPermissions) { 7774 boolean allowed; 7775 allowed = (compareSignatures( 7776 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 7777 == PackageManager.SIGNATURE_MATCH) 7778 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 7779 == PackageManager.SIGNATURE_MATCH); 7780 if (!allowed && (bp.protectionLevel 7781 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 7782 if (isSystemApp(pkg)) { 7783 // For updated system applications, a system permission 7784 // is granted only if it had been defined by the original application. 7785 if (pkg.isUpdatedSystemApp()) { 7786 final PackageSetting sysPs = mSettings 7787 .getDisabledSystemPkgLPr(pkg.packageName); 7788 if (sysPs.getPermissionsState().hasInstallPermission(perm)) { 7789 // If the original was granted this permission, we take 7790 // that grant decision as read and propagate it to the 7791 // update. 7792 if (sysPs.isPrivileged()) { 7793 allowed = true; 7794 } 7795 } else { 7796 // The system apk may have been updated with an older 7797 // version of the one on the data partition, but which 7798 // granted a new system permission that it didn't have 7799 // before. In this case we do want to allow the app to 7800 // now get the new permission if the ancestral apk is 7801 // privileged to get it. 7802 if (sysPs.pkg != null && sysPs.isPrivileged()) { 7803 for (int j=0; 7804 j<sysPs.pkg.requestedPermissions.size(); j++) { 7805 if (perm.equals( 7806 sysPs.pkg.requestedPermissions.get(j))) { 7807 allowed = true; 7808 break; 7809 } 7810 } 7811 } 7812 } 7813 } else { 7814 allowed = isPrivilegedApp(pkg); 7815 } 7816 } 7817 } 7818 if (!allowed && (bp.protectionLevel 7819 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 7820 // For development permissions, a development permission 7821 // is granted only if it was already granted. 7822 allowed = origPermissions.hasInstallPermission(perm); 7823 } 7824 return allowed; 7825 } 7826 7827 final class ActivityIntentResolver 7828 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 7829 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7830 boolean defaultOnly, int userId) { 7831 if (!sUserManager.exists(userId)) return null; 7832 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7833 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7834 } 7835 7836 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7837 int userId) { 7838 if (!sUserManager.exists(userId)) return null; 7839 mFlags = flags; 7840 return super.queryIntent(intent, resolvedType, 7841 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7842 } 7843 7844 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7845 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 7846 if (!sUserManager.exists(userId)) return null; 7847 if (packageActivities == null) { 7848 return null; 7849 } 7850 mFlags = flags; 7851 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 7852 final int N = packageActivities.size(); 7853 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 7854 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 7855 7856 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 7857 for (int i = 0; i < N; ++i) { 7858 intentFilters = packageActivities.get(i).intents; 7859 if (intentFilters != null && intentFilters.size() > 0) { 7860 PackageParser.ActivityIntentInfo[] array = 7861 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 7862 intentFilters.toArray(array); 7863 listCut.add(array); 7864 } 7865 } 7866 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7867 } 7868 7869 public final void addActivity(PackageParser.Activity a, String type) { 7870 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 7871 mActivities.put(a.getComponentName(), a); 7872 if (DEBUG_SHOW_INFO) 7873 Log.v( 7874 TAG, " " + type + " " + 7875 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 7876 if (DEBUG_SHOW_INFO) 7877 Log.v(TAG, " Class=" + a.info.name); 7878 final int NI = a.intents.size(); 7879 for (int j=0; j<NI; j++) { 7880 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7881 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 7882 intent.setPriority(0); 7883 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 7884 + a.className + " with priority > 0, forcing to 0"); 7885 } 7886 if (DEBUG_SHOW_INFO) { 7887 Log.v(TAG, " IntentFilter:"); 7888 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7889 } 7890 if (!intent.debugCheck()) { 7891 Log.w(TAG, "==> For Activity " + a.info.name); 7892 } 7893 addFilter(intent); 7894 } 7895 } 7896 7897 public final void removeActivity(PackageParser.Activity a, String type) { 7898 mActivities.remove(a.getComponentName()); 7899 if (DEBUG_SHOW_INFO) { 7900 Log.v(TAG, " " + type + " " 7901 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 7902 : a.info.name) + ":"); 7903 Log.v(TAG, " Class=" + a.info.name); 7904 } 7905 final int NI = a.intents.size(); 7906 for (int j=0; j<NI; j++) { 7907 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7908 if (DEBUG_SHOW_INFO) { 7909 Log.v(TAG, " IntentFilter:"); 7910 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7911 } 7912 removeFilter(intent); 7913 } 7914 } 7915 7916 @Override 7917 protected boolean allowFilterResult( 7918 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 7919 ActivityInfo filterAi = filter.activity.info; 7920 for (int i=dest.size()-1; i>=0; i--) { 7921 ActivityInfo destAi = dest.get(i).activityInfo; 7922 if (destAi.name == filterAi.name 7923 && destAi.packageName == filterAi.packageName) { 7924 return false; 7925 } 7926 } 7927 return true; 7928 } 7929 7930 @Override 7931 protected ActivityIntentInfo[] newArray(int size) { 7932 return new ActivityIntentInfo[size]; 7933 } 7934 7935 @Override 7936 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 7937 if (!sUserManager.exists(userId)) return true; 7938 PackageParser.Package p = filter.activity.owner; 7939 if (p != null) { 7940 PackageSetting ps = (PackageSetting)p.mExtras; 7941 if (ps != null) { 7942 // System apps are never considered stopped for purposes of 7943 // filtering, because there may be no way for the user to 7944 // actually re-launch them. 7945 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 7946 && ps.getStopped(userId); 7947 } 7948 } 7949 return false; 7950 } 7951 7952 @Override 7953 protected boolean isPackageForFilter(String packageName, 7954 PackageParser.ActivityIntentInfo info) { 7955 return packageName.equals(info.activity.owner.packageName); 7956 } 7957 7958 @Override 7959 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 7960 int match, int userId) { 7961 if (!sUserManager.exists(userId)) return null; 7962 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 7963 return null; 7964 } 7965 final PackageParser.Activity activity = info.activity; 7966 if (mSafeMode && (activity.info.applicationInfo.flags 7967 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7968 return null; 7969 } 7970 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 7971 if (ps == null) { 7972 return null; 7973 } 7974 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 7975 ps.readUserState(userId), userId); 7976 if (ai == null) { 7977 return null; 7978 } 7979 final ResolveInfo res = new ResolveInfo(); 7980 res.activityInfo = ai; 7981 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 7982 res.filter = info; 7983 } 7984 if (info != null) { 7985 res.handleAllWebDataURI = info.handleAllWebDataURI(); 7986 } 7987 res.priority = info.getPriority(); 7988 res.preferredOrder = activity.owner.mPreferredOrder; 7989 //System.out.println("Result: " + res.activityInfo.className + 7990 // " = " + res.priority); 7991 res.match = match; 7992 res.isDefault = info.hasDefault; 7993 res.labelRes = info.labelRes; 7994 res.nonLocalizedLabel = info.nonLocalizedLabel; 7995 if (userNeedsBadging(userId)) { 7996 res.noResourceId = true; 7997 } else { 7998 res.icon = info.icon; 7999 } 8000 res.system = res.activityInfo.applicationInfo.isSystemApp(); 8001 return res; 8002 } 8003 8004 @Override 8005 protected void sortResults(List<ResolveInfo> results) { 8006 Collections.sort(results, mResolvePrioritySorter); 8007 } 8008 8009 @Override 8010 protected void dumpFilter(PrintWriter out, String prefix, 8011 PackageParser.ActivityIntentInfo filter) { 8012 out.print(prefix); out.print( 8013 Integer.toHexString(System.identityHashCode(filter.activity))); 8014 out.print(' '); 8015 filter.activity.printComponentShortName(out); 8016 out.print(" filter "); 8017 out.println(Integer.toHexString(System.identityHashCode(filter))); 8018 } 8019 8020 @Override 8021 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 8022 return filter.activity; 8023 } 8024 8025 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8026 PackageParser.Activity activity = (PackageParser.Activity)label; 8027 out.print(prefix); out.print( 8028 Integer.toHexString(System.identityHashCode(activity))); 8029 out.print(' '); 8030 activity.printComponentShortName(out); 8031 if (count > 1) { 8032 out.print(" ("); out.print(count); out.print(" filters)"); 8033 } 8034 out.println(); 8035 } 8036 8037// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8038// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8039// final List<ResolveInfo> retList = Lists.newArrayList(); 8040// while (i.hasNext()) { 8041// final ResolveInfo resolveInfo = i.next(); 8042// if (isEnabledLP(resolveInfo.activityInfo)) { 8043// retList.add(resolveInfo); 8044// } 8045// } 8046// return retList; 8047// } 8048 8049 // Keys are String (activity class name), values are Activity. 8050 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 8051 = new ArrayMap<ComponentName, PackageParser.Activity>(); 8052 private int mFlags; 8053 } 8054 8055 private final class ServiceIntentResolver 8056 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 8057 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8058 boolean defaultOnly, int userId) { 8059 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8060 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8061 } 8062 8063 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8064 int userId) { 8065 if (!sUserManager.exists(userId)) return null; 8066 mFlags = flags; 8067 return super.queryIntent(intent, resolvedType, 8068 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8069 } 8070 8071 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8072 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 8073 if (!sUserManager.exists(userId)) return null; 8074 if (packageServices == null) { 8075 return null; 8076 } 8077 mFlags = flags; 8078 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8079 final int N = packageServices.size(); 8080 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 8081 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 8082 8083 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 8084 for (int i = 0; i < N; ++i) { 8085 intentFilters = packageServices.get(i).intents; 8086 if (intentFilters != null && intentFilters.size() > 0) { 8087 PackageParser.ServiceIntentInfo[] array = 8088 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 8089 intentFilters.toArray(array); 8090 listCut.add(array); 8091 } 8092 } 8093 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8094 } 8095 8096 public final void addService(PackageParser.Service s) { 8097 mServices.put(s.getComponentName(), s); 8098 if (DEBUG_SHOW_INFO) { 8099 Log.v(TAG, " " 8100 + (s.info.nonLocalizedLabel != null 8101 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8102 Log.v(TAG, " Class=" + s.info.name); 8103 } 8104 final int NI = s.intents.size(); 8105 int j; 8106 for (j=0; j<NI; j++) { 8107 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8108 if (DEBUG_SHOW_INFO) { 8109 Log.v(TAG, " IntentFilter:"); 8110 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8111 } 8112 if (!intent.debugCheck()) { 8113 Log.w(TAG, "==> For Service " + s.info.name); 8114 } 8115 addFilter(intent); 8116 } 8117 } 8118 8119 public final void removeService(PackageParser.Service s) { 8120 mServices.remove(s.getComponentName()); 8121 if (DEBUG_SHOW_INFO) { 8122 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 8123 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8124 Log.v(TAG, " Class=" + s.info.name); 8125 } 8126 final int NI = s.intents.size(); 8127 int j; 8128 for (j=0; j<NI; j++) { 8129 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8130 if (DEBUG_SHOW_INFO) { 8131 Log.v(TAG, " IntentFilter:"); 8132 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8133 } 8134 removeFilter(intent); 8135 } 8136 } 8137 8138 @Override 8139 protected boolean allowFilterResult( 8140 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 8141 ServiceInfo filterSi = filter.service.info; 8142 for (int i=dest.size()-1; i>=0; i--) { 8143 ServiceInfo destAi = dest.get(i).serviceInfo; 8144 if (destAi.name == filterSi.name 8145 && destAi.packageName == filterSi.packageName) { 8146 return false; 8147 } 8148 } 8149 return true; 8150 } 8151 8152 @Override 8153 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 8154 return new PackageParser.ServiceIntentInfo[size]; 8155 } 8156 8157 @Override 8158 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 8159 if (!sUserManager.exists(userId)) return true; 8160 PackageParser.Package p = filter.service.owner; 8161 if (p != null) { 8162 PackageSetting ps = (PackageSetting)p.mExtras; 8163 if (ps != null) { 8164 // System apps are never considered stopped for purposes of 8165 // filtering, because there may be no way for the user to 8166 // actually re-launch them. 8167 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8168 && ps.getStopped(userId); 8169 } 8170 } 8171 return false; 8172 } 8173 8174 @Override 8175 protected boolean isPackageForFilter(String packageName, 8176 PackageParser.ServiceIntentInfo info) { 8177 return packageName.equals(info.service.owner.packageName); 8178 } 8179 8180 @Override 8181 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 8182 int match, int userId) { 8183 if (!sUserManager.exists(userId)) return null; 8184 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 8185 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 8186 return null; 8187 } 8188 final PackageParser.Service service = info.service; 8189 if (mSafeMode && (service.info.applicationInfo.flags 8190 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8191 return null; 8192 } 8193 PackageSetting ps = (PackageSetting) service.owner.mExtras; 8194 if (ps == null) { 8195 return null; 8196 } 8197 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 8198 ps.readUserState(userId), userId); 8199 if (si == null) { 8200 return null; 8201 } 8202 final ResolveInfo res = new ResolveInfo(); 8203 res.serviceInfo = si; 8204 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 8205 res.filter = filter; 8206 } 8207 res.priority = info.getPriority(); 8208 res.preferredOrder = service.owner.mPreferredOrder; 8209 res.match = match; 8210 res.isDefault = info.hasDefault; 8211 res.labelRes = info.labelRes; 8212 res.nonLocalizedLabel = info.nonLocalizedLabel; 8213 res.icon = info.icon; 8214 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 8215 return res; 8216 } 8217 8218 @Override 8219 protected void sortResults(List<ResolveInfo> results) { 8220 Collections.sort(results, mResolvePrioritySorter); 8221 } 8222 8223 @Override 8224 protected void dumpFilter(PrintWriter out, String prefix, 8225 PackageParser.ServiceIntentInfo filter) { 8226 out.print(prefix); out.print( 8227 Integer.toHexString(System.identityHashCode(filter.service))); 8228 out.print(' '); 8229 filter.service.printComponentShortName(out); 8230 out.print(" filter "); 8231 out.println(Integer.toHexString(System.identityHashCode(filter))); 8232 } 8233 8234 @Override 8235 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 8236 return filter.service; 8237 } 8238 8239 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8240 PackageParser.Service service = (PackageParser.Service)label; 8241 out.print(prefix); out.print( 8242 Integer.toHexString(System.identityHashCode(service))); 8243 out.print(' '); 8244 service.printComponentShortName(out); 8245 if (count > 1) { 8246 out.print(" ("); out.print(count); out.print(" filters)"); 8247 } 8248 out.println(); 8249 } 8250 8251// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8252// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8253// final List<ResolveInfo> retList = Lists.newArrayList(); 8254// while (i.hasNext()) { 8255// final ResolveInfo resolveInfo = (ResolveInfo) i; 8256// if (isEnabledLP(resolveInfo.serviceInfo)) { 8257// retList.add(resolveInfo); 8258// } 8259// } 8260// return retList; 8261// } 8262 8263 // Keys are String (activity class name), values are Activity. 8264 private final ArrayMap<ComponentName, PackageParser.Service> mServices 8265 = new ArrayMap<ComponentName, PackageParser.Service>(); 8266 private int mFlags; 8267 }; 8268 8269 private final class ProviderIntentResolver 8270 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 8271 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8272 boolean defaultOnly, int userId) { 8273 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8274 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8275 } 8276 8277 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8278 int userId) { 8279 if (!sUserManager.exists(userId)) 8280 return null; 8281 mFlags = flags; 8282 return super.queryIntent(intent, resolvedType, 8283 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8284 } 8285 8286 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8287 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 8288 if (!sUserManager.exists(userId)) 8289 return null; 8290 if (packageProviders == null) { 8291 return null; 8292 } 8293 mFlags = flags; 8294 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 8295 final int N = packageProviders.size(); 8296 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 8297 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 8298 8299 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 8300 for (int i = 0; i < N; ++i) { 8301 intentFilters = packageProviders.get(i).intents; 8302 if (intentFilters != null && intentFilters.size() > 0) { 8303 PackageParser.ProviderIntentInfo[] array = 8304 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 8305 intentFilters.toArray(array); 8306 listCut.add(array); 8307 } 8308 } 8309 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8310 } 8311 8312 public final void addProvider(PackageParser.Provider p) { 8313 if (mProviders.containsKey(p.getComponentName())) { 8314 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 8315 return; 8316 } 8317 8318 mProviders.put(p.getComponentName(), p); 8319 if (DEBUG_SHOW_INFO) { 8320 Log.v(TAG, " " 8321 + (p.info.nonLocalizedLabel != null 8322 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8323 Log.v(TAG, " Class=" + p.info.name); 8324 } 8325 final int NI = p.intents.size(); 8326 int j; 8327 for (j = 0; j < NI; j++) { 8328 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8329 if (DEBUG_SHOW_INFO) { 8330 Log.v(TAG, " IntentFilter:"); 8331 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8332 } 8333 if (!intent.debugCheck()) { 8334 Log.w(TAG, "==> For Provider " + p.info.name); 8335 } 8336 addFilter(intent); 8337 } 8338 } 8339 8340 public final void removeProvider(PackageParser.Provider p) { 8341 mProviders.remove(p.getComponentName()); 8342 if (DEBUG_SHOW_INFO) { 8343 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 8344 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8345 Log.v(TAG, " Class=" + p.info.name); 8346 } 8347 final int NI = p.intents.size(); 8348 int j; 8349 for (j = 0; j < NI; j++) { 8350 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8351 if (DEBUG_SHOW_INFO) { 8352 Log.v(TAG, " IntentFilter:"); 8353 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8354 } 8355 removeFilter(intent); 8356 } 8357 } 8358 8359 @Override 8360 protected boolean allowFilterResult( 8361 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 8362 ProviderInfo filterPi = filter.provider.info; 8363 for (int i = dest.size() - 1; i >= 0; i--) { 8364 ProviderInfo destPi = dest.get(i).providerInfo; 8365 if (destPi.name == filterPi.name 8366 && destPi.packageName == filterPi.packageName) { 8367 return false; 8368 } 8369 } 8370 return true; 8371 } 8372 8373 @Override 8374 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 8375 return new PackageParser.ProviderIntentInfo[size]; 8376 } 8377 8378 @Override 8379 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 8380 if (!sUserManager.exists(userId)) 8381 return true; 8382 PackageParser.Package p = filter.provider.owner; 8383 if (p != null) { 8384 PackageSetting ps = (PackageSetting) p.mExtras; 8385 if (ps != null) { 8386 // System apps are never considered stopped for purposes of 8387 // filtering, because there may be no way for the user to 8388 // actually re-launch them. 8389 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8390 && ps.getStopped(userId); 8391 } 8392 } 8393 return false; 8394 } 8395 8396 @Override 8397 protected boolean isPackageForFilter(String packageName, 8398 PackageParser.ProviderIntentInfo info) { 8399 return packageName.equals(info.provider.owner.packageName); 8400 } 8401 8402 @Override 8403 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 8404 int match, int userId) { 8405 if (!sUserManager.exists(userId)) 8406 return null; 8407 final PackageParser.ProviderIntentInfo info = filter; 8408 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 8409 return null; 8410 } 8411 final PackageParser.Provider provider = info.provider; 8412 if (mSafeMode && (provider.info.applicationInfo.flags 8413 & ApplicationInfo.FLAG_SYSTEM) == 0) { 8414 return null; 8415 } 8416 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 8417 if (ps == null) { 8418 return null; 8419 } 8420 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 8421 ps.readUserState(userId), userId); 8422 if (pi == null) { 8423 return null; 8424 } 8425 final ResolveInfo res = new ResolveInfo(); 8426 res.providerInfo = pi; 8427 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 8428 res.filter = filter; 8429 } 8430 res.priority = info.getPriority(); 8431 res.preferredOrder = provider.owner.mPreferredOrder; 8432 res.match = match; 8433 res.isDefault = info.hasDefault; 8434 res.labelRes = info.labelRes; 8435 res.nonLocalizedLabel = info.nonLocalizedLabel; 8436 res.icon = info.icon; 8437 res.system = res.providerInfo.applicationInfo.isSystemApp(); 8438 return res; 8439 } 8440 8441 @Override 8442 protected void sortResults(List<ResolveInfo> results) { 8443 Collections.sort(results, mResolvePrioritySorter); 8444 } 8445 8446 @Override 8447 protected void dumpFilter(PrintWriter out, String prefix, 8448 PackageParser.ProviderIntentInfo filter) { 8449 out.print(prefix); 8450 out.print( 8451 Integer.toHexString(System.identityHashCode(filter.provider))); 8452 out.print(' '); 8453 filter.provider.printComponentShortName(out); 8454 out.print(" filter "); 8455 out.println(Integer.toHexString(System.identityHashCode(filter))); 8456 } 8457 8458 @Override 8459 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 8460 return filter.provider; 8461 } 8462 8463 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8464 PackageParser.Provider provider = (PackageParser.Provider)label; 8465 out.print(prefix); out.print( 8466 Integer.toHexString(System.identityHashCode(provider))); 8467 out.print(' '); 8468 provider.printComponentShortName(out); 8469 if (count > 1) { 8470 out.print(" ("); out.print(count); out.print(" filters)"); 8471 } 8472 out.println(); 8473 } 8474 8475 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 8476 = new ArrayMap<ComponentName, PackageParser.Provider>(); 8477 private int mFlags; 8478 }; 8479 8480 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 8481 new Comparator<ResolveInfo>() { 8482 public int compare(ResolveInfo r1, ResolveInfo r2) { 8483 int v1 = r1.priority; 8484 int v2 = r2.priority; 8485 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 8486 if (v1 != v2) { 8487 return (v1 > v2) ? -1 : 1; 8488 } 8489 v1 = r1.preferredOrder; 8490 v2 = r2.preferredOrder; 8491 if (v1 != v2) { 8492 return (v1 > v2) ? -1 : 1; 8493 } 8494 if (r1.isDefault != r2.isDefault) { 8495 return r1.isDefault ? -1 : 1; 8496 } 8497 v1 = r1.match; 8498 v2 = r2.match; 8499 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 8500 if (v1 != v2) { 8501 return (v1 > v2) ? -1 : 1; 8502 } 8503 if (r1.system != r2.system) { 8504 return r1.system ? -1 : 1; 8505 } 8506 return 0; 8507 } 8508 }; 8509 8510 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 8511 new Comparator<ProviderInfo>() { 8512 public int compare(ProviderInfo p1, ProviderInfo p2) { 8513 final int v1 = p1.initOrder; 8514 final int v2 = p2.initOrder; 8515 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 8516 } 8517 }; 8518 8519 final void sendPackageBroadcast(final String action, final String pkg, 8520 final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver, 8521 final int[] userIds) { 8522 mHandler.post(new Runnable() { 8523 @Override 8524 public void run() { 8525 try { 8526 final IActivityManager am = ActivityManagerNative.getDefault(); 8527 if (am == null) return; 8528 final int[] resolvedUserIds; 8529 if (userIds == null) { 8530 resolvedUserIds = am.getRunningUserIds(); 8531 } else { 8532 resolvedUserIds = userIds; 8533 } 8534 for (int id : resolvedUserIds) { 8535 final Intent intent = new Intent(action, 8536 pkg != null ? Uri.fromParts("package", pkg, null) : null); 8537 if (extras != null) { 8538 intent.putExtras(extras); 8539 } 8540 if (targetPkg != null) { 8541 intent.setPackage(targetPkg); 8542 } 8543 // Modify the UID when posting to other users 8544 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 8545 if (uid > 0 && UserHandle.getUserId(uid) != id) { 8546 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 8547 intent.putExtra(Intent.EXTRA_UID, uid); 8548 } 8549 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 8550 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 8551 if (DEBUG_BROADCASTS) { 8552 RuntimeException here = new RuntimeException("here"); 8553 here.fillInStackTrace(); 8554 Slog.d(TAG, "Sending to user " + id + ": " 8555 + intent.toShortString(false, true, false, false) 8556 + " " + intent.getExtras(), here); 8557 } 8558 am.broadcastIntent(null, intent, null, finishedReceiver, 8559 0, null, null, null, android.app.AppOpsManager.OP_NONE, 8560 finishedReceiver != null, false, id); 8561 } 8562 } catch (RemoteException ex) { 8563 } 8564 } 8565 }); 8566 } 8567 8568 /** 8569 * Check if the external storage media is available. This is true if there 8570 * is a mounted external storage medium or if the external storage is 8571 * emulated. 8572 */ 8573 private boolean isExternalMediaAvailable() { 8574 return mMediaMounted || Environment.isExternalStorageEmulated(); 8575 } 8576 8577 @Override 8578 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 8579 // writer 8580 synchronized (mPackages) { 8581 if (!isExternalMediaAvailable()) { 8582 // If the external storage is no longer mounted at this point, 8583 // the caller may not have been able to delete all of this 8584 // packages files and can not delete any more. Bail. 8585 return null; 8586 } 8587 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 8588 if (lastPackage != null) { 8589 pkgs.remove(lastPackage); 8590 } 8591 if (pkgs.size() > 0) { 8592 return pkgs.get(0); 8593 } 8594 } 8595 return null; 8596 } 8597 8598 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 8599 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 8600 userId, andCode ? 1 : 0, packageName); 8601 if (mSystemReady) { 8602 msg.sendToTarget(); 8603 } else { 8604 if (mPostSystemReadyMessages == null) { 8605 mPostSystemReadyMessages = new ArrayList<>(); 8606 } 8607 mPostSystemReadyMessages.add(msg); 8608 } 8609 } 8610 8611 void startCleaningPackages() { 8612 // reader 8613 synchronized (mPackages) { 8614 if (!isExternalMediaAvailable()) { 8615 return; 8616 } 8617 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 8618 return; 8619 } 8620 } 8621 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 8622 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 8623 IActivityManager am = ActivityManagerNative.getDefault(); 8624 if (am != null) { 8625 try { 8626 am.startService(null, intent, null, UserHandle.USER_OWNER); 8627 } catch (RemoteException e) { 8628 } 8629 } 8630 } 8631 8632 @Override 8633 public void installPackage(String originPath, IPackageInstallObserver2 observer, 8634 int installFlags, String installerPackageName, VerificationParams verificationParams, 8635 String packageAbiOverride) { 8636 installPackageAsUser(originPath, observer, installFlags, installerPackageName, 8637 verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); 8638 } 8639 8640 @Override 8641 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 8642 int installFlags, String installerPackageName, VerificationParams verificationParams, 8643 String packageAbiOverride, int userId) { 8644 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 8645 8646 final int callingUid = Binder.getCallingUid(); 8647 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 8648 8649 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8650 try { 8651 if (observer != null) { 8652 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 8653 } 8654 } catch (RemoteException re) { 8655 } 8656 return; 8657 } 8658 8659 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 8660 installFlags |= PackageManager.INSTALL_FROM_ADB; 8661 8662 } else { 8663 // Caller holds INSTALL_PACKAGES permission, so we're less strict 8664 // about installerPackageName. 8665 8666 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 8667 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 8668 } 8669 8670 UserHandle user; 8671 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 8672 user = UserHandle.ALL; 8673 } else { 8674 user = new UserHandle(userId); 8675 } 8676 8677 // Only system components can circumvent runtime permissions when installing. 8678 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 8679 && mContext.checkCallingOrSelfPermission(Manifest.permission 8680 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 8681 throw new SecurityException("You need the " 8682 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 8683 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 8684 } 8685 8686 verificationParams.setInstallerUid(callingUid); 8687 8688 final File originFile = new File(originPath); 8689 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 8690 8691 final Message msg = mHandler.obtainMessage(INIT_COPY); 8692 msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName, 8693 null, verificationParams, user, packageAbiOverride); 8694 mHandler.sendMessage(msg); 8695 } 8696 8697 void installStage(String packageName, File stagedDir, String stagedCid, 8698 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, 8699 String installerPackageName, int installerUid, UserHandle user) { 8700 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 8701 params.referrerUri, installerUid, null); 8702 8703 final OriginInfo origin; 8704 if (stagedDir != null) { 8705 origin = OriginInfo.fromStagedFile(stagedDir); 8706 } else { 8707 origin = OriginInfo.fromStagedContainer(stagedCid); 8708 } 8709 8710 final Message msg = mHandler.obtainMessage(INIT_COPY); 8711 msg.obj = new InstallParams(origin, null, observer, params.installFlags, 8712 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride); 8713 mHandler.sendMessage(msg); 8714 } 8715 8716 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 8717 Bundle extras = new Bundle(1); 8718 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 8719 8720 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 8721 packageName, extras, null, null, new int[] {userId}); 8722 try { 8723 IActivityManager am = ActivityManagerNative.getDefault(); 8724 final boolean isSystem = 8725 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 8726 if (isSystem && am.isUserRunning(userId, false)) { 8727 // The just-installed/enabled app is bundled on the system, so presumed 8728 // to be able to run automatically without needing an explicit launch. 8729 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 8730 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 8731 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 8732 .setPackage(packageName); 8733 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 8734 android.app.AppOpsManager.OP_NONE, false, false, userId); 8735 } 8736 } catch (RemoteException e) { 8737 // shouldn't happen 8738 Slog.w(TAG, "Unable to bootstrap installed package", e); 8739 } 8740 } 8741 8742 @Override 8743 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 8744 int userId) { 8745 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8746 PackageSetting pkgSetting; 8747 final int uid = Binder.getCallingUid(); 8748 enforceCrossUserPermission(uid, userId, true, true, 8749 "setApplicationHiddenSetting for user " + userId); 8750 8751 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 8752 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 8753 return false; 8754 } 8755 8756 long callingId = Binder.clearCallingIdentity(); 8757 try { 8758 boolean sendAdded = false; 8759 boolean sendRemoved = false; 8760 // writer 8761 synchronized (mPackages) { 8762 pkgSetting = mSettings.mPackages.get(packageName); 8763 if (pkgSetting == null) { 8764 return false; 8765 } 8766 if (pkgSetting.getHidden(userId) != hidden) { 8767 pkgSetting.setHidden(hidden, userId); 8768 mSettings.writePackageRestrictionsLPr(userId); 8769 if (hidden) { 8770 sendRemoved = true; 8771 } else { 8772 sendAdded = true; 8773 } 8774 } 8775 } 8776 if (sendAdded) { 8777 sendPackageAddedForUser(packageName, pkgSetting, userId); 8778 return true; 8779 } 8780 if (sendRemoved) { 8781 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 8782 "hiding pkg"); 8783 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 8784 } 8785 } finally { 8786 Binder.restoreCallingIdentity(callingId); 8787 } 8788 return false; 8789 } 8790 8791 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 8792 int userId) { 8793 final PackageRemovedInfo info = new PackageRemovedInfo(); 8794 info.removedPackage = packageName; 8795 info.removedUsers = new int[] {userId}; 8796 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 8797 info.sendBroadcast(false, false, false); 8798 } 8799 8800 /** 8801 * Returns true if application is not found or there was an error. Otherwise it returns 8802 * the hidden state of the package for the given user. 8803 */ 8804 @Override 8805 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 8806 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8807 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 8808 false, "getApplicationHidden for user " + userId); 8809 PackageSetting pkgSetting; 8810 long callingId = Binder.clearCallingIdentity(); 8811 try { 8812 // writer 8813 synchronized (mPackages) { 8814 pkgSetting = mSettings.mPackages.get(packageName); 8815 if (pkgSetting == null) { 8816 return true; 8817 } 8818 return pkgSetting.getHidden(userId); 8819 } 8820 } finally { 8821 Binder.restoreCallingIdentity(callingId); 8822 } 8823 } 8824 8825 /** 8826 * @hide 8827 */ 8828 @Override 8829 public int installExistingPackageAsUser(String packageName, int userId) { 8830 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 8831 null); 8832 PackageSetting pkgSetting; 8833 final int uid = Binder.getCallingUid(); 8834 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 8835 + userId); 8836 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8837 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 8838 } 8839 8840 long callingId = Binder.clearCallingIdentity(); 8841 try { 8842 boolean sendAdded = false; 8843 8844 // writer 8845 synchronized (mPackages) { 8846 pkgSetting = mSettings.mPackages.get(packageName); 8847 if (pkgSetting == null) { 8848 return PackageManager.INSTALL_FAILED_INVALID_URI; 8849 } 8850 if (!pkgSetting.getInstalled(userId)) { 8851 pkgSetting.setInstalled(true, userId); 8852 pkgSetting.setHidden(false, userId); 8853 mSettings.writePackageRestrictionsLPr(userId); 8854 sendAdded = true; 8855 } 8856 } 8857 8858 if (sendAdded) { 8859 sendPackageAddedForUser(packageName, pkgSetting, userId); 8860 } 8861 } finally { 8862 Binder.restoreCallingIdentity(callingId); 8863 } 8864 8865 return PackageManager.INSTALL_SUCCEEDED; 8866 } 8867 8868 boolean isUserRestricted(int userId, String restrictionKey) { 8869 Bundle restrictions = sUserManager.getUserRestrictions(userId); 8870 if (restrictions.getBoolean(restrictionKey, false)) { 8871 Log.w(TAG, "User is restricted: " + restrictionKey); 8872 return true; 8873 } 8874 return false; 8875 } 8876 8877 @Override 8878 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 8879 mContext.enforceCallingOrSelfPermission( 8880 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8881 "Only package verification agents can verify applications"); 8882 8883 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8884 final PackageVerificationResponse response = new PackageVerificationResponse( 8885 verificationCode, Binder.getCallingUid()); 8886 msg.arg1 = id; 8887 msg.obj = response; 8888 mHandler.sendMessage(msg); 8889 } 8890 8891 @Override 8892 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 8893 long millisecondsToDelay) { 8894 mContext.enforceCallingOrSelfPermission( 8895 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8896 "Only package verification agents can extend verification timeouts"); 8897 8898 final PackageVerificationState state = mPendingVerification.get(id); 8899 final PackageVerificationResponse response = new PackageVerificationResponse( 8900 verificationCodeAtTimeout, Binder.getCallingUid()); 8901 8902 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 8903 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 8904 } 8905 if (millisecondsToDelay < 0) { 8906 millisecondsToDelay = 0; 8907 } 8908 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 8909 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 8910 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 8911 } 8912 8913 if ((state != null) && !state.timeoutExtended()) { 8914 state.extendTimeout(); 8915 8916 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8917 msg.arg1 = id; 8918 msg.obj = response; 8919 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 8920 } 8921 } 8922 8923 private void broadcastPackageVerified(int verificationId, Uri packageUri, 8924 int verificationCode, UserHandle user) { 8925 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 8926 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 8927 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 8928 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 8929 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 8930 8931 mContext.sendBroadcastAsUser(intent, user, 8932 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 8933 } 8934 8935 private ComponentName matchComponentForVerifier(String packageName, 8936 List<ResolveInfo> receivers) { 8937 ActivityInfo targetReceiver = null; 8938 8939 final int NR = receivers.size(); 8940 for (int i = 0; i < NR; i++) { 8941 final ResolveInfo info = receivers.get(i); 8942 if (info.activityInfo == null) { 8943 continue; 8944 } 8945 8946 if (packageName.equals(info.activityInfo.packageName)) { 8947 targetReceiver = info.activityInfo; 8948 break; 8949 } 8950 } 8951 8952 if (targetReceiver == null) { 8953 return null; 8954 } 8955 8956 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 8957 } 8958 8959 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 8960 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 8961 if (pkgInfo.verifiers.length == 0) { 8962 return null; 8963 } 8964 8965 final int N = pkgInfo.verifiers.length; 8966 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 8967 for (int i = 0; i < N; i++) { 8968 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 8969 8970 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 8971 receivers); 8972 if (comp == null) { 8973 continue; 8974 } 8975 8976 final int verifierUid = getUidForVerifier(verifierInfo); 8977 if (verifierUid == -1) { 8978 continue; 8979 } 8980 8981 if (DEBUG_VERIFY) { 8982 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 8983 + " with the correct signature"); 8984 } 8985 sufficientVerifiers.add(comp); 8986 verificationState.addSufficientVerifier(verifierUid); 8987 } 8988 8989 return sufficientVerifiers; 8990 } 8991 8992 private int getUidForVerifier(VerifierInfo verifierInfo) { 8993 synchronized (mPackages) { 8994 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 8995 if (pkg == null) { 8996 return -1; 8997 } else if (pkg.mSignatures.length != 1) { 8998 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8999 + " has more than one signature; ignoring"); 9000 return -1; 9001 } 9002 9003 /* 9004 * If the public key of the package's signature does not match 9005 * our expected public key, then this is a different package and 9006 * we should skip. 9007 */ 9008 9009 final byte[] expectedPublicKey; 9010 try { 9011 final Signature verifierSig = pkg.mSignatures[0]; 9012 final PublicKey publicKey = verifierSig.getPublicKey(); 9013 expectedPublicKey = publicKey.getEncoded(); 9014 } catch (CertificateException e) { 9015 return -1; 9016 } 9017 9018 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 9019 9020 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 9021 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 9022 + " does not have the expected public key; ignoring"); 9023 return -1; 9024 } 9025 9026 return pkg.applicationInfo.uid; 9027 } 9028 } 9029 9030 @Override 9031 public void finishPackageInstall(int token) { 9032 enforceSystemOrRoot("Only the system is allowed to finish installs"); 9033 9034 if (DEBUG_INSTALL) { 9035 Slog.v(TAG, "BM finishing package install for " + token); 9036 } 9037 9038 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9039 mHandler.sendMessage(msg); 9040 } 9041 9042 /** 9043 * Get the verification agent timeout. 9044 * 9045 * @return verification timeout in milliseconds 9046 */ 9047 private long getVerificationTimeout() { 9048 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 9049 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 9050 DEFAULT_VERIFICATION_TIMEOUT); 9051 } 9052 9053 /** 9054 * Get the default verification agent response code. 9055 * 9056 * @return default verification response code 9057 */ 9058 private int getDefaultVerificationResponse() { 9059 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9060 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 9061 DEFAULT_VERIFICATION_RESPONSE); 9062 } 9063 9064 /** 9065 * Check whether or not package verification has been enabled. 9066 * 9067 * @return true if verification should be performed 9068 */ 9069 private boolean isVerificationEnabled(int userId, int installFlags) { 9070 if (!DEFAULT_VERIFY_ENABLE) { 9071 return false; 9072 } 9073 9074 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 9075 9076 // Check if installing from ADB 9077 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 9078 // Do not run verification in a test harness environment 9079 if (ActivityManager.isRunningInTestHarness()) { 9080 return false; 9081 } 9082 if (ensureVerifyAppsEnabled) { 9083 return true; 9084 } 9085 // Check if the developer does not want package verification for ADB installs 9086 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9087 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 9088 return false; 9089 } 9090 } 9091 9092 if (ensureVerifyAppsEnabled) { 9093 return true; 9094 } 9095 9096 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9097 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 9098 } 9099 9100 @Override 9101 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 9102 throws RemoteException { 9103 mContext.enforceCallingOrSelfPermission( 9104 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 9105 "Only intentfilter verification agents can verify applications"); 9106 9107 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 9108 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 9109 Binder.getCallingUid(), verificationCode, failedDomains); 9110 msg.arg1 = id; 9111 msg.obj = response; 9112 mHandler.sendMessage(msg); 9113 } 9114 9115 @Override 9116 public int getIntentVerificationStatus(String packageName, int userId) { 9117 synchronized (mPackages) { 9118 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 9119 } 9120 } 9121 9122 @Override 9123 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 9124 boolean result = false; 9125 synchronized (mPackages) { 9126 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 9127 } 9128 scheduleWritePackageRestrictionsLocked(userId); 9129 return result; 9130 } 9131 9132 @Override 9133 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 9134 synchronized (mPackages) { 9135 return mSettings.getIntentFilterVerificationsLPr(packageName); 9136 } 9137 } 9138 9139 @Override 9140 public List<IntentFilter> getAllIntentFilters(String packageName) { 9141 if (TextUtils.isEmpty(packageName)) { 9142 return Collections.<IntentFilter>emptyList(); 9143 } 9144 synchronized (mPackages) { 9145 PackageParser.Package pkg = mPackages.get(packageName); 9146 if (pkg == null || pkg.activities == null) { 9147 return Collections.<IntentFilter>emptyList(); 9148 } 9149 final int count = pkg.activities.size(); 9150 ArrayList<IntentFilter> result = new ArrayList<>(); 9151 for (int n=0; n<count; n++) { 9152 PackageParser.Activity activity = pkg.activities.get(n); 9153 if (activity.intents != null || activity.intents.size() > 0) { 9154 result.addAll(activity.intents); 9155 } 9156 } 9157 return result; 9158 } 9159 } 9160 9161 @Override 9162 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 9163 synchronized (mPackages) { 9164 boolean result = mSettings.setDefaultBrowserPackageNameLPr(packageName, userId); 9165 result |= updateIntentVerificationStatus(packageName, 9166 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 9167 UserHandle.myUserId()); 9168 return result; 9169 } 9170 } 9171 9172 @Override 9173 public String getDefaultBrowserPackageName(int userId) { 9174 synchronized (mPackages) { 9175 return mSettings.getDefaultBrowserPackageNameLPw(userId); 9176 } 9177 } 9178 9179 /** 9180 * Get the "allow unknown sources" setting. 9181 * 9182 * @return the current "allow unknown sources" setting 9183 */ 9184 private int getUnknownSourcesSettings() { 9185 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9186 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 9187 -1); 9188 } 9189 9190 @Override 9191 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 9192 final int uid = Binder.getCallingUid(); 9193 // writer 9194 synchronized (mPackages) { 9195 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 9196 if (targetPackageSetting == null) { 9197 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 9198 } 9199 9200 PackageSetting installerPackageSetting; 9201 if (installerPackageName != null) { 9202 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 9203 if (installerPackageSetting == null) { 9204 throw new IllegalArgumentException("Unknown installer package: " 9205 + installerPackageName); 9206 } 9207 } else { 9208 installerPackageSetting = null; 9209 } 9210 9211 Signature[] callerSignature; 9212 Object obj = mSettings.getUserIdLPr(uid); 9213 if (obj != null) { 9214 if (obj instanceof SharedUserSetting) { 9215 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 9216 } else if (obj instanceof PackageSetting) { 9217 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 9218 } else { 9219 throw new SecurityException("Bad object " + obj + " for uid " + uid); 9220 } 9221 } else { 9222 throw new SecurityException("Unknown calling uid " + uid); 9223 } 9224 9225 // Verify: can't set installerPackageName to a package that is 9226 // not signed with the same cert as the caller. 9227 if (installerPackageSetting != null) { 9228 if (compareSignatures(callerSignature, 9229 installerPackageSetting.signatures.mSignatures) 9230 != PackageManager.SIGNATURE_MATCH) { 9231 throw new SecurityException( 9232 "Caller does not have same cert as new installer package " 9233 + installerPackageName); 9234 } 9235 } 9236 9237 // Verify: if target already has an installer package, it must 9238 // be signed with the same cert as the caller. 9239 if (targetPackageSetting.installerPackageName != null) { 9240 PackageSetting setting = mSettings.mPackages.get( 9241 targetPackageSetting.installerPackageName); 9242 // If the currently set package isn't valid, then it's always 9243 // okay to change it. 9244 if (setting != null) { 9245 if (compareSignatures(callerSignature, 9246 setting.signatures.mSignatures) 9247 != PackageManager.SIGNATURE_MATCH) { 9248 throw new SecurityException( 9249 "Caller does not have same cert as old installer package " 9250 + targetPackageSetting.installerPackageName); 9251 } 9252 } 9253 } 9254 9255 // Okay! 9256 targetPackageSetting.installerPackageName = installerPackageName; 9257 scheduleWriteSettingsLocked(); 9258 } 9259 } 9260 9261 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 9262 // Queue up an async operation since the package installation may take a little while. 9263 mHandler.post(new Runnable() { 9264 public void run() { 9265 mHandler.removeCallbacks(this); 9266 // Result object to be returned 9267 PackageInstalledInfo res = new PackageInstalledInfo(); 9268 res.returnCode = currentStatus; 9269 res.uid = -1; 9270 res.pkg = null; 9271 res.removedInfo = new PackageRemovedInfo(); 9272 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 9273 args.doPreInstall(res.returnCode); 9274 synchronized (mInstallLock) { 9275 installPackageLI(args, res); 9276 } 9277 args.doPostInstall(res.returnCode, res.uid); 9278 } 9279 9280 // A restore should be performed at this point if (a) the install 9281 // succeeded, (b) the operation is not an update, and (c) the new 9282 // package has not opted out of backup participation. 9283 final boolean update = res.removedInfo.removedPackage != null; 9284 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 9285 boolean doRestore = !update 9286 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 9287 9288 // Set up the post-install work request bookkeeping. This will be used 9289 // and cleaned up by the post-install event handling regardless of whether 9290 // there's a restore pass performed. Token values are >= 1. 9291 int token; 9292 if (mNextInstallToken < 0) mNextInstallToken = 1; 9293 token = mNextInstallToken++; 9294 9295 PostInstallData data = new PostInstallData(args, res); 9296 mRunningInstalls.put(token, data); 9297 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 9298 9299 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 9300 // Pass responsibility to the Backup Manager. It will perform a 9301 // restore if appropriate, then pass responsibility back to the 9302 // Package Manager to run the post-install observer callbacks 9303 // and broadcasts. 9304 IBackupManager bm = IBackupManager.Stub.asInterface( 9305 ServiceManager.getService(Context.BACKUP_SERVICE)); 9306 if (bm != null) { 9307 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 9308 + " to BM for possible restore"); 9309 try { 9310 if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { 9311 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 9312 } else { 9313 doRestore = false; 9314 } 9315 } catch (RemoteException e) { 9316 // can't happen; the backup manager is local 9317 } catch (Exception e) { 9318 Slog.e(TAG, "Exception trying to enqueue restore", e); 9319 doRestore = false; 9320 } 9321 } else { 9322 Slog.e(TAG, "Backup Manager not found!"); 9323 doRestore = false; 9324 } 9325 } 9326 9327 if (!doRestore) { 9328 // No restore possible, or the Backup Manager was mysteriously not 9329 // available -- just fire the post-install work request directly. 9330 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 9331 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9332 mHandler.sendMessage(msg); 9333 } 9334 } 9335 }); 9336 } 9337 9338 private abstract class HandlerParams { 9339 private static final int MAX_RETRIES = 4; 9340 9341 /** 9342 * Number of times startCopy() has been attempted and had a non-fatal 9343 * error. 9344 */ 9345 private int mRetries = 0; 9346 9347 /** User handle for the user requesting the information or installation. */ 9348 private final UserHandle mUser; 9349 9350 HandlerParams(UserHandle user) { 9351 mUser = user; 9352 } 9353 9354 UserHandle getUser() { 9355 return mUser; 9356 } 9357 9358 final boolean startCopy() { 9359 boolean res; 9360 try { 9361 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 9362 9363 if (++mRetries > MAX_RETRIES) { 9364 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 9365 mHandler.sendEmptyMessage(MCS_GIVE_UP); 9366 handleServiceError(); 9367 return false; 9368 } else { 9369 handleStartCopy(); 9370 res = true; 9371 } 9372 } catch (RemoteException e) { 9373 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 9374 mHandler.sendEmptyMessage(MCS_RECONNECT); 9375 res = false; 9376 } 9377 handleReturnCode(); 9378 return res; 9379 } 9380 9381 final void serviceError() { 9382 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 9383 handleServiceError(); 9384 handleReturnCode(); 9385 } 9386 9387 abstract void handleStartCopy() throws RemoteException; 9388 abstract void handleServiceError(); 9389 abstract void handleReturnCode(); 9390 } 9391 9392 class MeasureParams extends HandlerParams { 9393 private final PackageStats mStats; 9394 private boolean mSuccess; 9395 9396 private final IPackageStatsObserver mObserver; 9397 9398 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 9399 super(new UserHandle(stats.userHandle)); 9400 mObserver = observer; 9401 mStats = stats; 9402 } 9403 9404 @Override 9405 public String toString() { 9406 return "MeasureParams{" 9407 + Integer.toHexString(System.identityHashCode(this)) 9408 + " " + mStats.packageName + "}"; 9409 } 9410 9411 @Override 9412 void handleStartCopy() throws RemoteException { 9413 synchronized (mInstallLock) { 9414 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 9415 } 9416 9417 if (mSuccess) { 9418 final boolean mounted; 9419 if (Environment.isExternalStorageEmulated()) { 9420 mounted = true; 9421 } else { 9422 final String status = Environment.getExternalStorageState(); 9423 mounted = (Environment.MEDIA_MOUNTED.equals(status) 9424 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 9425 } 9426 9427 if (mounted) { 9428 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 9429 9430 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 9431 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 9432 9433 mStats.externalDataSize = calculateDirectorySize(mContainerService, 9434 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 9435 9436 // Always subtract cache size, since it's a subdirectory 9437 mStats.externalDataSize -= mStats.externalCacheSize; 9438 9439 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 9440 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 9441 9442 mStats.externalObbSize = calculateDirectorySize(mContainerService, 9443 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 9444 } 9445 } 9446 } 9447 9448 @Override 9449 void handleReturnCode() { 9450 if (mObserver != null) { 9451 try { 9452 mObserver.onGetStatsCompleted(mStats, mSuccess); 9453 } catch (RemoteException e) { 9454 Slog.i(TAG, "Observer no longer exists."); 9455 } 9456 } 9457 } 9458 9459 @Override 9460 void handleServiceError() { 9461 Slog.e(TAG, "Could not measure application " + mStats.packageName 9462 + " external storage"); 9463 } 9464 } 9465 9466 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 9467 throws RemoteException { 9468 long result = 0; 9469 for (File path : paths) { 9470 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 9471 } 9472 return result; 9473 } 9474 9475 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 9476 for (File path : paths) { 9477 try { 9478 mcs.clearDirectory(path.getAbsolutePath()); 9479 } catch (RemoteException e) { 9480 } 9481 } 9482 } 9483 9484 static class OriginInfo { 9485 /** 9486 * Location where install is coming from, before it has been 9487 * copied/renamed into place. This could be a single monolithic APK 9488 * file, or a cluster directory. This location may be untrusted. 9489 */ 9490 final File file; 9491 final String cid; 9492 9493 /** 9494 * Flag indicating that {@link #file} or {@link #cid} has already been 9495 * staged, meaning downstream users don't need to defensively copy the 9496 * contents. 9497 */ 9498 final boolean staged; 9499 9500 /** 9501 * Flag indicating that {@link #file} or {@link #cid} is an already 9502 * installed app that is being moved. 9503 */ 9504 final boolean existing; 9505 9506 final String resolvedPath; 9507 final File resolvedFile; 9508 9509 static OriginInfo fromNothing() { 9510 return new OriginInfo(null, null, false, false); 9511 } 9512 9513 static OriginInfo fromUntrustedFile(File file) { 9514 return new OriginInfo(file, null, false, false); 9515 } 9516 9517 static OriginInfo fromExistingFile(File file) { 9518 return new OriginInfo(file, null, false, true); 9519 } 9520 9521 static OriginInfo fromStagedFile(File file) { 9522 return new OriginInfo(file, null, true, false); 9523 } 9524 9525 static OriginInfo fromStagedContainer(String cid) { 9526 return new OriginInfo(null, cid, true, false); 9527 } 9528 9529 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 9530 this.file = file; 9531 this.cid = cid; 9532 this.staged = staged; 9533 this.existing = existing; 9534 9535 if (cid != null) { 9536 resolvedPath = PackageHelper.getSdDir(cid); 9537 resolvedFile = new File(resolvedPath); 9538 } else if (file != null) { 9539 resolvedPath = file.getAbsolutePath(); 9540 resolvedFile = file; 9541 } else { 9542 resolvedPath = null; 9543 resolvedFile = null; 9544 } 9545 } 9546 } 9547 9548 class MoveInfo { 9549 final int moveId; 9550 final String fromUuid; 9551 final String toUuid; 9552 final String packageName; 9553 final String dataAppName; 9554 final int appId; 9555 final String seinfo; 9556 9557 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 9558 String dataAppName, int appId, String seinfo) { 9559 this.moveId = moveId; 9560 this.fromUuid = fromUuid; 9561 this.toUuid = toUuid; 9562 this.packageName = packageName; 9563 this.dataAppName = dataAppName; 9564 this.appId = appId; 9565 this.seinfo = seinfo; 9566 } 9567 } 9568 9569 class InstallParams extends HandlerParams { 9570 final OriginInfo origin; 9571 final MoveInfo move; 9572 final IPackageInstallObserver2 observer; 9573 int installFlags; 9574 final String installerPackageName; 9575 final String volumeUuid; 9576 final VerificationParams verificationParams; 9577 private InstallArgs mArgs; 9578 private int mRet; 9579 final String packageAbiOverride; 9580 9581 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 9582 int installFlags, String installerPackageName, String volumeUuid, 9583 VerificationParams verificationParams, UserHandle user, String packageAbiOverride) { 9584 super(user); 9585 this.origin = origin; 9586 this.move = move; 9587 this.observer = observer; 9588 this.installFlags = installFlags; 9589 this.installerPackageName = installerPackageName; 9590 this.volumeUuid = volumeUuid; 9591 this.verificationParams = verificationParams; 9592 this.packageAbiOverride = packageAbiOverride; 9593 } 9594 9595 @Override 9596 public String toString() { 9597 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 9598 + " file=" + origin.file + " cid=" + origin.cid + "}"; 9599 } 9600 9601 public ManifestDigest getManifestDigest() { 9602 if (verificationParams == null) { 9603 return null; 9604 } 9605 return verificationParams.getManifestDigest(); 9606 } 9607 9608 private int installLocationPolicy(PackageInfoLite pkgLite) { 9609 String packageName = pkgLite.packageName; 9610 int installLocation = pkgLite.installLocation; 9611 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9612 // reader 9613 synchronized (mPackages) { 9614 PackageParser.Package pkg = mPackages.get(packageName); 9615 if (pkg != null) { 9616 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 9617 // Check for downgrading. 9618 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 9619 try { 9620 checkDowngrade(pkg, pkgLite); 9621 } catch (PackageManagerException e) { 9622 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 9623 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 9624 } 9625 } 9626 // Check for updated system application. 9627 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9628 if (onSd) { 9629 Slog.w(TAG, "Cannot install update to system app on sdcard"); 9630 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 9631 } 9632 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9633 } else { 9634 if (onSd) { 9635 // Install flag overrides everything. 9636 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9637 } 9638 // If current upgrade specifies particular preference 9639 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 9640 // Application explicitly specified internal. 9641 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9642 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 9643 // App explictly prefers external. Let policy decide 9644 } else { 9645 // Prefer previous location 9646 if (isExternal(pkg)) { 9647 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9648 } 9649 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9650 } 9651 } 9652 } else { 9653 // Invalid install. Return error code 9654 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 9655 } 9656 } 9657 } 9658 // All the special cases have been taken care of. 9659 // Return result based on recommended install location. 9660 if (onSd) { 9661 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9662 } 9663 return pkgLite.recommendedInstallLocation; 9664 } 9665 9666 /* 9667 * Invoke remote method to get package information and install 9668 * location values. Override install location based on default 9669 * policy if needed and then create install arguments based 9670 * on the install location. 9671 */ 9672 public void handleStartCopy() throws RemoteException { 9673 int ret = PackageManager.INSTALL_SUCCEEDED; 9674 9675 // If we're already staged, we've firmly committed to an install location 9676 if (origin.staged) { 9677 if (origin.file != null) { 9678 installFlags |= PackageManager.INSTALL_INTERNAL; 9679 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9680 } else if (origin.cid != null) { 9681 installFlags |= PackageManager.INSTALL_EXTERNAL; 9682 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9683 } else { 9684 throw new IllegalStateException("Invalid stage location"); 9685 } 9686 } 9687 9688 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9689 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 9690 9691 PackageInfoLite pkgLite = null; 9692 9693 if (onInt && onSd) { 9694 // Check if both bits are set. 9695 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 9696 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9697 } else { 9698 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 9699 packageAbiOverride); 9700 9701 /* 9702 * If we have too little free space, try to free cache 9703 * before giving up. 9704 */ 9705 if (!origin.staged && pkgLite.recommendedInstallLocation 9706 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9707 // TODO: focus freeing disk space on the target device 9708 final StorageManager storage = StorageManager.from(mContext); 9709 final long lowThreshold = storage.getStorageLowBytes( 9710 Environment.getDataDirectory()); 9711 9712 final long sizeBytes = mContainerService.calculateInstalledSize( 9713 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 9714 9715 if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) { 9716 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 9717 installFlags, packageAbiOverride); 9718 } 9719 9720 /* 9721 * The cache free must have deleted the file we 9722 * downloaded to install. 9723 * 9724 * TODO: fix the "freeCache" call to not delete 9725 * the file we care about. 9726 */ 9727 if (pkgLite.recommendedInstallLocation 9728 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9729 pkgLite.recommendedInstallLocation 9730 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 9731 } 9732 } 9733 } 9734 9735 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9736 int loc = pkgLite.recommendedInstallLocation; 9737 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 9738 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9739 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 9740 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9741 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9742 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9743 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 9744 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 9745 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9746 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 9747 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 9748 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 9749 } else { 9750 // Override with defaults if needed. 9751 loc = installLocationPolicy(pkgLite); 9752 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 9753 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 9754 } else if (!onSd && !onInt) { 9755 // Override install location with flags 9756 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 9757 // Set the flag to install on external media. 9758 installFlags |= PackageManager.INSTALL_EXTERNAL; 9759 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9760 } else { 9761 // Make sure the flag for installing on external 9762 // media is unset 9763 installFlags |= PackageManager.INSTALL_INTERNAL; 9764 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9765 } 9766 } 9767 } 9768 } 9769 9770 final InstallArgs args = createInstallArgs(this); 9771 mArgs = args; 9772 9773 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9774 /* 9775 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 9776 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 9777 */ 9778 int userIdentifier = getUser().getIdentifier(); 9779 if (userIdentifier == UserHandle.USER_ALL 9780 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) { 9781 userIdentifier = UserHandle.USER_OWNER; 9782 } 9783 9784 /* 9785 * Determine if we have any installed package verifiers. If we 9786 * do, then we'll defer to them to verify the packages. 9787 */ 9788 final int requiredUid = mRequiredVerifierPackage == null ? -1 9789 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 9790 if (!origin.existing && requiredUid != -1 9791 && isVerificationEnabled(userIdentifier, installFlags)) { 9792 final Intent verification = new Intent( 9793 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 9794 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9795 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 9796 PACKAGE_MIME_TYPE); 9797 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 9798 9799 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 9800 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 9801 0 /* TODO: Which userId? */); 9802 9803 if (DEBUG_VERIFY) { 9804 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 9805 + verification.toString() + " with " + pkgLite.verifiers.length 9806 + " optional verifiers"); 9807 } 9808 9809 final int verificationId = mPendingVerificationToken++; 9810 9811 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 9812 9813 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 9814 installerPackageName); 9815 9816 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 9817 installFlags); 9818 9819 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 9820 pkgLite.packageName); 9821 9822 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 9823 pkgLite.versionCode); 9824 9825 if (verificationParams != null) { 9826 if (verificationParams.getVerificationURI() != null) { 9827 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 9828 verificationParams.getVerificationURI()); 9829 } 9830 if (verificationParams.getOriginatingURI() != null) { 9831 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 9832 verificationParams.getOriginatingURI()); 9833 } 9834 if (verificationParams.getReferrer() != null) { 9835 verification.putExtra(Intent.EXTRA_REFERRER, 9836 verificationParams.getReferrer()); 9837 } 9838 if (verificationParams.getOriginatingUid() >= 0) { 9839 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 9840 verificationParams.getOriginatingUid()); 9841 } 9842 if (verificationParams.getInstallerUid() >= 0) { 9843 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 9844 verificationParams.getInstallerUid()); 9845 } 9846 } 9847 9848 final PackageVerificationState verificationState = new PackageVerificationState( 9849 requiredUid, args); 9850 9851 mPendingVerification.append(verificationId, verificationState); 9852 9853 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 9854 receivers, verificationState); 9855 9856 /* 9857 * If any sufficient verifiers were listed in the package 9858 * manifest, attempt to ask them. 9859 */ 9860 if (sufficientVerifiers != null) { 9861 final int N = sufficientVerifiers.size(); 9862 if (N == 0) { 9863 Slog.i(TAG, "Additional verifiers required, but none installed."); 9864 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 9865 } else { 9866 for (int i = 0; i < N; i++) { 9867 final ComponentName verifierComponent = sufficientVerifiers.get(i); 9868 9869 final Intent sufficientIntent = new Intent(verification); 9870 sufficientIntent.setComponent(verifierComponent); 9871 9872 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 9873 } 9874 } 9875 } 9876 9877 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 9878 mRequiredVerifierPackage, receivers); 9879 if (ret == PackageManager.INSTALL_SUCCEEDED 9880 && mRequiredVerifierPackage != null) { 9881 /* 9882 * Send the intent to the required verification agent, 9883 * but only start the verification timeout after the 9884 * target BroadcastReceivers have run. 9885 */ 9886 verification.setComponent(requiredVerifierComponent); 9887 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 9888 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9889 new BroadcastReceiver() { 9890 @Override 9891 public void onReceive(Context context, Intent intent) { 9892 final Message msg = mHandler 9893 .obtainMessage(CHECK_PENDING_VERIFICATION); 9894 msg.arg1 = verificationId; 9895 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 9896 } 9897 }, null, 0, null, null); 9898 9899 /* 9900 * We don't want the copy to proceed until verification 9901 * succeeds, so null out this field. 9902 */ 9903 mArgs = null; 9904 } 9905 } else { 9906 /* 9907 * No package verification is enabled, so immediately start 9908 * the remote call to initiate copy using temporary file. 9909 */ 9910 ret = args.copyApk(mContainerService, true); 9911 } 9912 } 9913 9914 mRet = ret; 9915 } 9916 9917 @Override 9918 void handleReturnCode() { 9919 // If mArgs is null, then MCS couldn't be reached. When it 9920 // reconnects, it will try again to install. At that point, this 9921 // will succeed. 9922 if (mArgs != null) { 9923 processPendingInstall(mArgs, mRet); 9924 } 9925 } 9926 9927 @Override 9928 void handleServiceError() { 9929 mArgs = createInstallArgs(this); 9930 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 9931 } 9932 9933 public boolean isForwardLocked() { 9934 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9935 } 9936 } 9937 9938 /** 9939 * Used during creation of InstallArgs 9940 * 9941 * @param installFlags package installation flags 9942 * @return true if should be installed on external storage 9943 */ 9944 private static boolean installOnExternalAsec(int installFlags) { 9945 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 9946 return false; 9947 } 9948 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 9949 return true; 9950 } 9951 return false; 9952 } 9953 9954 /** 9955 * Used during creation of InstallArgs 9956 * 9957 * @param installFlags package installation flags 9958 * @return true if should be installed as forward locked 9959 */ 9960 private static boolean installForwardLocked(int installFlags) { 9961 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9962 } 9963 9964 private InstallArgs createInstallArgs(InstallParams params) { 9965 if (params.move != null) { 9966 return new MoveInstallArgs(params); 9967 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 9968 return new AsecInstallArgs(params); 9969 } else { 9970 return new FileInstallArgs(params); 9971 } 9972 } 9973 9974 /** 9975 * Create args that describe an existing installed package. Typically used 9976 * when cleaning up old installs, or used as a move source. 9977 */ 9978 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 9979 String resourcePath, String[] instructionSets) { 9980 final boolean isInAsec; 9981 if (installOnExternalAsec(installFlags)) { 9982 /* Apps on SD card are always in ASEC containers. */ 9983 isInAsec = true; 9984 } else if (installForwardLocked(installFlags) 9985 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 9986 /* 9987 * Forward-locked apps are only in ASEC containers if they're the 9988 * new style 9989 */ 9990 isInAsec = true; 9991 } else { 9992 isInAsec = false; 9993 } 9994 9995 if (isInAsec) { 9996 return new AsecInstallArgs(codePath, instructionSets, 9997 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 9998 } else { 9999 return new FileInstallArgs(codePath, resourcePath, instructionSets); 10000 } 10001 } 10002 10003 static abstract class InstallArgs { 10004 /** @see InstallParams#origin */ 10005 final OriginInfo origin; 10006 /** @see InstallParams#move */ 10007 final MoveInfo move; 10008 10009 final IPackageInstallObserver2 observer; 10010 // Always refers to PackageManager flags only 10011 final int installFlags; 10012 final String installerPackageName; 10013 final String volumeUuid; 10014 final ManifestDigest manifestDigest; 10015 final UserHandle user; 10016 final String abiOverride; 10017 10018 // The list of instruction sets supported by this app. This is currently 10019 // only used during the rmdex() phase to clean up resources. We can get rid of this 10020 // if we move dex files under the common app path. 10021 /* nullable */ String[] instructionSets; 10022 10023 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 10024 int installFlags, String installerPackageName, String volumeUuid, 10025 ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, 10026 String abiOverride) { 10027 this.origin = origin; 10028 this.move = move; 10029 this.installFlags = installFlags; 10030 this.observer = observer; 10031 this.installerPackageName = installerPackageName; 10032 this.volumeUuid = volumeUuid; 10033 this.manifestDigest = manifestDigest; 10034 this.user = user; 10035 this.instructionSets = instructionSets; 10036 this.abiOverride = abiOverride; 10037 } 10038 10039 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 10040 abstract int doPreInstall(int status); 10041 10042 /** 10043 * Rename package into final resting place. All paths on the given 10044 * scanned package should be updated to reflect the rename. 10045 */ 10046 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 10047 abstract int doPostInstall(int status, int uid); 10048 10049 /** @see PackageSettingBase#codePathString */ 10050 abstract String getCodePath(); 10051 /** @see PackageSettingBase#resourcePathString */ 10052 abstract String getResourcePath(); 10053 10054 // Need installer lock especially for dex file removal. 10055 abstract void cleanUpResourcesLI(); 10056 abstract boolean doPostDeleteLI(boolean delete); 10057 10058 /** 10059 * Called before the source arguments are copied. This is used mostly 10060 * for MoveParams when it needs to read the source file to put it in the 10061 * destination. 10062 */ 10063 int doPreCopy() { 10064 return PackageManager.INSTALL_SUCCEEDED; 10065 } 10066 10067 /** 10068 * Called after the source arguments are copied. This is used mostly for 10069 * MoveParams when it needs to read the source file to put it in the 10070 * destination. 10071 * 10072 * @return 10073 */ 10074 int doPostCopy(int uid) { 10075 return PackageManager.INSTALL_SUCCEEDED; 10076 } 10077 10078 protected boolean isFwdLocked() { 10079 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 10080 } 10081 10082 protected boolean isExternalAsec() { 10083 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10084 } 10085 10086 UserHandle getUser() { 10087 return user; 10088 } 10089 } 10090 10091 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 10092 if (!allCodePaths.isEmpty()) { 10093 if (instructionSets == null) { 10094 throw new IllegalStateException("instructionSet == null"); 10095 } 10096 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 10097 for (String codePath : allCodePaths) { 10098 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 10099 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 10100 if (retCode < 0) { 10101 Slog.w(TAG, "Couldn't remove dex file for package: " 10102 + " at location " + codePath + ", retcode=" + retCode); 10103 // we don't consider this to be a failure of the core package deletion 10104 } 10105 } 10106 } 10107 } 10108 } 10109 10110 /** 10111 * Logic to handle installation of non-ASEC applications, including copying 10112 * and renaming logic. 10113 */ 10114 class FileInstallArgs extends InstallArgs { 10115 private File codeFile; 10116 private File resourceFile; 10117 10118 // Example topology: 10119 // /data/app/com.example/base.apk 10120 // /data/app/com.example/split_foo.apk 10121 // /data/app/com.example/lib/arm/libfoo.so 10122 // /data/app/com.example/lib/arm64/libfoo.so 10123 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 10124 10125 /** New install */ 10126 FileInstallArgs(InstallParams params) { 10127 super(params.origin, params.move, params.observer, params.installFlags, 10128 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10129 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10130 if (isFwdLocked()) { 10131 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 10132 } 10133 } 10134 10135 /** Existing install */ 10136 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 10137 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets, 10138 null); 10139 this.codeFile = (codePath != null) ? new File(codePath) : null; 10140 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 10141 } 10142 10143 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10144 if (origin.staged) { 10145 Slog.d(TAG, origin.file + " already staged; skipping copy"); 10146 codeFile = origin.file; 10147 resourceFile = origin.file; 10148 return PackageManager.INSTALL_SUCCEEDED; 10149 } 10150 10151 try { 10152 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid); 10153 codeFile = tempDir; 10154 resourceFile = tempDir; 10155 } catch (IOException e) { 10156 Slog.w(TAG, "Failed to create copy file: " + e); 10157 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10158 } 10159 10160 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 10161 @Override 10162 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 10163 if (!FileUtils.isValidExtFilename(name)) { 10164 throw new IllegalArgumentException("Invalid filename: " + name); 10165 } 10166 try { 10167 final File file = new File(codeFile, name); 10168 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 10169 O_RDWR | O_CREAT, 0644); 10170 Os.chmod(file.getAbsolutePath(), 0644); 10171 return new ParcelFileDescriptor(fd); 10172 } catch (ErrnoException e) { 10173 throw new RemoteException("Failed to open: " + e.getMessage()); 10174 } 10175 } 10176 }; 10177 10178 int ret = PackageManager.INSTALL_SUCCEEDED; 10179 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 10180 if (ret != PackageManager.INSTALL_SUCCEEDED) { 10181 Slog.e(TAG, "Failed to copy package"); 10182 return ret; 10183 } 10184 10185 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 10186 NativeLibraryHelper.Handle handle = null; 10187 try { 10188 handle = NativeLibraryHelper.Handle.create(codeFile); 10189 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 10190 abiOverride); 10191 } catch (IOException e) { 10192 Slog.e(TAG, "Copying native libraries failed", e); 10193 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10194 } finally { 10195 IoUtils.closeQuietly(handle); 10196 } 10197 10198 return ret; 10199 } 10200 10201 int doPreInstall(int status) { 10202 if (status != PackageManager.INSTALL_SUCCEEDED) { 10203 cleanUp(); 10204 } 10205 return status; 10206 } 10207 10208 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10209 if (status != PackageManager.INSTALL_SUCCEEDED) { 10210 cleanUp(); 10211 return false; 10212 } 10213 10214 final File targetDir = codeFile.getParentFile(); 10215 final File beforeCodeFile = codeFile; 10216 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 10217 10218 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 10219 try { 10220 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 10221 } catch (ErrnoException e) { 10222 Slog.d(TAG, "Failed to rename", e); 10223 return false; 10224 } 10225 10226 if (!SELinux.restoreconRecursive(afterCodeFile)) { 10227 Slog.d(TAG, "Failed to restorecon"); 10228 return false; 10229 } 10230 10231 // Reflect the rename internally 10232 codeFile = afterCodeFile; 10233 resourceFile = afterCodeFile; 10234 10235 // Reflect the rename in scanned details 10236 pkg.codePath = afterCodeFile.getAbsolutePath(); 10237 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10238 pkg.baseCodePath); 10239 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10240 pkg.splitCodePaths); 10241 10242 // Reflect the rename in app info 10243 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10244 pkg.applicationInfo.setCodePath(pkg.codePath); 10245 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10246 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10247 pkg.applicationInfo.setResourcePath(pkg.codePath); 10248 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10249 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10250 10251 return true; 10252 } 10253 10254 int doPostInstall(int status, int uid) { 10255 if (status != PackageManager.INSTALL_SUCCEEDED) { 10256 cleanUp(); 10257 } 10258 return status; 10259 } 10260 10261 @Override 10262 String getCodePath() { 10263 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 10264 } 10265 10266 @Override 10267 String getResourcePath() { 10268 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 10269 } 10270 10271 private boolean cleanUp() { 10272 if (codeFile == null || !codeFile.exists()) { 10273 return false; 10274 } 10275 10276 if (codeFile.isDirectory()) { 10277 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 10278 } else { 10279 codeFile.delete(); 10280 } 10281 10282 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 10283 resourceFile.delete(); 10284 } 10285 10286 return true; 10287 } 10288 10289 void cleanUpResourcesLI() { 10290 // Try enumerating all code paths before deleting 10291 List<String> allCodePaths = Collections.EMPTY_LIST; 10292 if (codeFile != null && codeFile.exists()) { 10293 try { 10294 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10295 allCodePaths = pkg.getAllCodePaths(); 10296 } catch (PackageParserException e) { 10297 // Ignored; we tried our best 10298 } 10299 } 10300 10301 cleanUp(); 10302 removeDexFiles(allCodePaths, instructionSets); 10303 } 10304 10305 boolean doPostDeleteLI(boolean delete) { 10306 // XXX err, shouldn't we respect the delete flag? 10307 cleanUpResourcesLI(); 10308 return true; 10309 } 10310 } 10311 10312 private boolean isAsecExternal(String cid) { 10313 final String asecPath = PackageHelper.getSdFilesystem(cid); 10314 return !asecPath.startsWith(mAsecInternalPath); 10315 } 10316 10317 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 10318 PackageManagerException { 10319 if (copyRet < 0) { 10320 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 10321 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 10322 throw new PackageManagerException(copyRet, message); 10323 } 10324 } 10325 } 10326 10327 /** 10328 * Extract the MountService "container ID" from the full code path of an 10329 * .apk. 10330 */ 10331 static String cidFromCodePath(String fullCodePath) { 10332 int eidx = fullCodePath.lastIndexOf("/"); 10333 String subStr1 = fullCodePath.substring(0, eidx); 10334 int sidx = subStr1.lastIndexOf("/"); 10335 return subStr1.substring(sidx+1, eidx); 10336 } 10337 10338 /** 10339 * Logic to handle installation of ASEC applications, including copying and 10340 * renaming logic. 10341 */ 10342 class AsecInstallArgs extends InstallArgs { 10343 static final String RES_FILE_NAME = "pkg.apk"; 10344 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 10345 10346 String cid; 10347 String packagePath; 10348 String resourcePath; 10349 10350 /** New install */ 10351 AsecInstallArgs(InstallParams params) { 10352 super(params.origin, params.move, params.observer, params.installFlags, 10353 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10354 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10355 } 10356 10357 /** Existing install */ 10358 AsecInstallArgs(String fullCodePath, String[] instructionSets, 10359 boolean isExternal, boolean isForwardLocked) { 10360 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 10361 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10362 instructionSets, null); 10363 // Hackily pretend we're still looking at a full code path 10364 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 10365 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 10366 } 10367 10368 // Extract cid from fullCodePath 10369 int eidx = fullCodePath.lastIndexOf("/"); 10370 String subStr1 = fullCodePath.substring(0, eidx); 10371 int sidx = subStr1.lastIndexOf("/"); 10372 cid = subStr1.substring(sidx+1, eidx); 10373 setMountPath(subStr1); 10374 } 10375 10376 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 10377 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 10378 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10379 instructionSets, null); 10380 this.cid = cid; 10381 setMountPath(PackageHelper.getSdDir(cid)); 10382 } 10383 10384 void createCopyFile() { 10385 cid = mInstallerService.allocateExternalStageCidLegacy(); 10386 } 10387 10388 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10389 if (origin.staged) { 10390 Slog.d(TAG, origin.cid + " already staged; skipping copy"); 10391 cid = origin.cid; 10392 setMountPath(PackageHelper.getSdDir(cid)); 10393 return PackageManager.INSTALL_SUCCEEDED; 10394 } 10395 10396 if (temp) { 10397 createCopyFile(); 10398 } else { 10399 /* 10400 * Pre-emptively destroy the container since it's destroyed if 10401 * copying fails due to it existing anyway. 10402 */ 10403 PackageHelper.destroySdDir(cid); 10404 } 10405 10406 final String newMountPath = imcs.copyPackageToContainer( 10407 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 10408 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 10409 10410 if (newMountPath != null) { 10411 setMountPath(newMountPath); 10412 return PackageManager.INSTALL_SUCCEEDED; 10413 } else { 10414 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10415 } 10416 } 10417 10418 @Override 10419 String getCodePath() { 10420 return packagePath; 10421 } 10422 10423 @Override 10424 String getResourcePath() { 10425 return resourcePath; 10426 } 10427 10428 int doPreInstall(int status) { 10429 if (status != PackageManager.INSTALL_SUCCEEDED) { 10430 // Destroy container 10431 PackageHelper.destroySdDir(cid); 10432 } else { 10433 boolean mounted = PackageHelper.isContainerMounted(cid); 10434 if (!mounted) { 10435 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 10436 Process.SYSTEM_UID); 10437 if (newMountPath != null) { 10438 setMountPath(newMountPath); 10439 } else { 10440 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10441 } 10442 } 10443 } 10444 return status; 10445 } 10446 10447 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10448 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 10449 String newMountPath = null; 10450 if (PackageHelper.isContainerMounted(cid)) { 10451 // Unmount the container 10452 if (!PackageHelper.unMountSdDir(cid)) { 10453 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 10454 return false; 10455 } 10456 } 10457 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10458 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 10459 " which might be stale. Will try to clean up."); 10460 // Clean up the stale container and proceed to recreate. 10461 if (!PackageHelper.destroySdDir(newCacheId)) { 10462 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 10463 return false; 10464 } 10465 // Successfully cleaned up stale container. Try to rename again. 10466 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10467 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 10468 + " inspite of cleaning it up."); 10469 return false; 10470 } 10471 } 10472 if (!PackageHelper.isContainerMounted(newCacheId)) { 10473 Slog.w(TAG, "Mounting container " + newCacheId); 10474 newMountPath = PackageHelper.mountSdDir(newCacheId, 10475 getEncryptKey(), Process.SYSTEM_UID); 10476 } else { 10477 newMountPath = PackageHelper.getSdDir(newCacheId); 10478 } 10479 if (newMountPath == null) { 10480 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 10481 return false; 10482 } 10483 Log.i(TAG, "Succesfully renamed " + cid + 10484 " to " + newCacheId + 10485 " at new path: " + newMountPath); 10486 cid = newCacheId; 10487 10488 final File beforeCodeFile = new File(packagePath); 10489 setMountPath(newMountPath); 10490 final File afterCodeFile = new File(packagePath); 10491 10492 // Reflect the rename in scanned details 10493 pkg.codePath = afterCodeFile.getAbsolutePath(); 10494 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10495 pkg.baseCodePath); 10496 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10497 pkg.splitCodePaths); 10498 10499 // Reflect the rename in app info 10500 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10501 pkg.applicationInfo.setCodePath(pkg.codePath); 10502 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10503 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10504 pkg.applicationInfo.setResourcePath(pkg.codePath); 10505 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10506 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10507 10508 return true; 10509 } 10510 10511 private void setMountPath(String mountPath) { 10512 final File mountFile = new File(mountPath); 10513 10514 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 10515 if (monolithicFile.exists()) { 10516 packagePath = monolithicFile.getAbsolutePath(); 10517 if (isFwdLocked()) { 10518 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 10519 } else { 10520 resourcePath = packagePath; 10521 } 10522 } else { 10523 packagePath = mountFile.getAbsolutePath(); 10524 resourcePath = packagePath; 10525 } 10526 } 10527 10528 int doPostInstall(int status, int uid) { 10529 if (status != PackageManager.INSTALL_SUCCEEDED) { 10530 cleanUp(); 10531 } else { 10532 final int groupOwner; 10533 final String protectedFile; 10534 if (isFwdLocked()) { 10535 groupOwner = UserHandle.getSharedAppGid(uid); 10536 protectedFile = RES_FILE_NAME; 10537 } else { 10538 groupOwner = -1; 10539 protectedFile = null; 10540 } 10541 10542 if (uid < Process.FIRST_APPLICATION_UID 10543 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 10544 Slog.e(TAG, "Failed to finalize " + cid); 10545 PackageHelper.destroySdDir(cid); 10546 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10547 } 10548 10549 boolean mounted = PackageHelper.isContainerMounted(cid); 10550 if (!mounted) { 10551 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 10552 } 10553 } 10554 return status; 10555 } 10556 10557 private void cleanUp() { 10558 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 10559 10560 // Destroy secure container 10561 PackageHelper.destroySdDir(cid); 10562 } 10563 10564 private List<String> getAllCodePaths() { 10565 final File codeFile = new File(getCodePath()); 10566 if (codeFile != null && codeFile.exists()) { 10567 try { 10568 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10569 return pkg.getAllCodePaths(); 10570 } catch (PackageParserException e) { 10571 // Ignored; we tried our best 10572 } 10573 } 10574 return Collections.EMPTY_LIST; 10575 } 10576 10577 void cleanUpResourcesLI() { 10578 // Enumerate all code paths before deleting 10579 cleanUpResourcesLI(getAllCodePaths()); 10580 } 10581 10582 private void cleanUpResourcesLI(List<String> allCodePaths) { 10583 cleanUp(); 10584 removeDexFiles(allCodePaths, instructionSets); 10585 } 10586 10587 String getPackageName() { 10588 return getAsecPackageName(cid); 10589 } 10590 10591 boolean doPostDeleteLI(boolean delete) { 10592 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 10593 final List<String> allCodePaths = getAllCodePaths(); 10594 boolean mounted = PackageHelper.isContainerMounted(cid); 10595 if (mounted) { 10596 // Unmount first 10597 if (PackageHelper.unMountSdDir(cid)) { 10598 mounted = false; 10599 } 10600 } 10601 if (!mounted && delete) { 10602 cleanUpResourcesLI(allCodePaths); 10603 } 10604 return !mounted; 10605 } 10606 10607 @Override 10608 int doPreCopy() { 10609 if (isFwdLocked()) { 10610 if (!PackageHelper.fixSdPermissions(cid, 10611 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 10612 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10613 } 10614 } 10615 10616 return PackageManager.INSTALL_SUCCEEDED; 10617 } 10618 10619 @Override 10620 int doPostCopy(int uid) { 10621 if (isFwdLocked()) { 10622 if (uid < Process.FIRST_APPLICATION_UID 10623 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 10624 RES_FILE_NAME)) { 10625 Slog.e(TAG, "Failed to finalize " + cid); 10626 PackageHelper.destroySdDir(cid); 10627 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10628 } 10629 } 10630 10631 return PackageManager.INSTALL_SUCCEEDED; 10632 } 10633 } 10634 10635 /** 10636 * Logic to handle movement of existing installed applications. 10637 */ 10638 class MoveInstallArgs extends InstallArgs { 10639 private File codeFile; 10640 private File resourceFile; 10641 10642 /** New install */ 10643 MoveInstallArgs(InstallParams params) { 10644 super(params.origin, params.move, params.observer, params.installFlags, 10645 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10646 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10647 } 10648 10649 int copyApk(IMediaContainerService imcs, boolean temp) { 10650 Slog.d(TAG, "Moving " + move.packageName + " from " + move.fromUuid + " to " 10651 + move.toUuid); 10652 synchronized (mInstaller) { 10653 if (mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 10654 move.dataAppName, move.appId, move.seinfo) != 0) { 10655 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10656 } 10657 } 10658 10659 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 10660 resourceFile = codeFile; 10661 Slog.d(TAG, "codeFile after move is " + codeFile); 10662 10663 return PackageManager.INSTALL_SUCCEEDED; 10664 } 10665 10666 int doPreInstall(int status) { 10667 if (status != PackageManager.INSTALL_SUCCEEDED) { 10668 cleanUp(); 10669 } 10670 return status; 10671 } 10672 10673 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10674 if (status != PackageManager.INSTALL_SUCCEEDED) { 10675 cleanUp(); 10676 return false; 10677 } 10678 10679 // Reflect the move in app info 10680 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10681 pkg.applicationInfo.setCodePath(pkg.codePath); 10682 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10683 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10684 pkg.applicationInfo.setResourcePath(pkg.codePath); 10685 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10686 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10687 10688 return true; 10689 } 10690 10691 int doPostInstall(int status, int uid) { 10692 if (status != PackageManager.INSTALL_SUCCEEDED) { 10693 cleanUp(); 10694 } 10695 return status; 10696 } 10697 10698 @Override 10699 String getCodePath() { 10700 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 10701 } 10702 10703 @Override 10704 String getResourcePath() { 10705 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 10706 } 10707 10708 private boolean cleanUp() { 10709 if (codeFile == null || !codeFile.exists()) { 10710 return false; 10711 } 10712 10713 if (codeFile.isDirectory()) { 10714 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 10715 } else { 10716 codeFile.delete(); 10717 } 10718 10719 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 10720 resourceFile.delete(); 10721 } 10722 10723 return true; 10724 } 10725 10726 void cleanUpResourcesLI() { 10727 cleanUp(); 10728 } 10729 10730 boolean doPostDeleteLI(boolean delete) { 10731 // XXX err, shouldn't we respect the delete flag? 10732 cleanUpResourcesLI(); 10733 return true; 10734 } 10735 } 10736 10737 static String getAsecPackageName(String packageCid) { 10738 int idx = packageCid.lastIndexOf("-"); 10739 if (idx == -1) { 10740 return packageCid; 10741 } 10742 return packageCid.substring(0, idx); 10743 } 10744 10745 // Utility method used to create code paths based on package name and available index. 10746 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 10747 String idxStr = ""; 10748 int idx = 1; 10749 // Fall back to default value of idx=1 if prefix is not 10750 // part of oldCodePath 10751 if (oldCodePath != null) { 10752 String subStr = oldCodePath; 10753 // Drop the suffix right away 10754 if (suffix != null && subStr.endsWith(suffix)) { 10755 subStr = subStr.substring(0, subStr.length() - suffix.length()); 10756 } 10757 // If oldCodePath already contains prefix find out the 10758 // ending index to either increment or decrement. 10759 int sidx = subStr.lastIndexOf(prefix); 10760 if (sidx != -1) { 10761 subStr = subStr.substring(sidx + prefix.length()); 10762 if (subStr != null) { 10763 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 10764 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 10765 } 10766 try { 10767 idx = Integer.parseInt(subStr); 10768 if (idx <= 1) { 10769 idx++; 10770 } else { 10771 idx--; 10772 } 10773 } catch(NumberFormatException e) { 10774 } 10775 } 10776 } 10777 } 10778 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 10779 return prefix + idxStr; 10780 } 10781 10782 private File getNextCodePath(File targetDir, String packageName) { 10783 int suffix = 1; 10784 File result; 10785 do { 10786 result = new File(targetDir, packageName + "-" + suffix); 10787 suffix++; 10788 } while (result.exists()); 10789 return result; 10790 } 10791 10792 // Utility method that returns the relative package path with respect 10793 // to the installation directory. Like say for /data/data/com.test-1.apk 10794 // string com.test-1 is returned. 10795 static String deriveCodePathName(String codePath) { 10796 if (codePath == null) { 10797 return null; 10798 } 10799 final File codeFile = new File(codePath); 10800 final String name = codeFile.getName(); 10801 if (codeFile.isDirectory()) { 10802 return name; 10803 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 10804 final int lastDot = name.lastIndexOf('.'); 10805 return name.substring(0, lastDot); 10806 } else { 10807 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 10808 return null; 10809 } 10810 } 10811 10812 class PackageInstalledInfo { 10813 String name; 10814 int uid; 10815 // The set of users that originally had this package installed. 10816 int[] origUsers; 10817 // The set of users that now have this package installed. 10818 int[] newUsers; 10819 PackageParser.Package pkg; 10820 int returnCode; 10821 String returnMsg; 10822 PackageRemovedInfo removedInfo; 10823 10824 public void setError(int code, String msg) { 10825 returnCode = code; 10826 returnMsg = msg; 10827 Slog.w(TAG, msg); 10828 } 10829 10830 public void setError(String msg, PackageParserException e) { 10831 returnCode = e.error; 10832 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10833 Slog.w(TAG, msg, e); 10834 } 10835 10836 public void setError(String msg, PackageManagerException e) { 10837 returnCode = e.error; 10838 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10839 Slog.w(TAG, msg, e); 10840 } 10841 10842 // In some error cases we want to convey more info back to the observer 10843 String origPackage; 10844 String origPermission; 10845 } 10846 10847 /* 10848 * Install a non-existing package. 10849 */ 10850 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 10851 UserHandle user, String installerPackageName, String volumeUuid, 10852 PackageInstalledInfo res) { 10853 // Remember this for later, in case we need to rollback this install 10854 String pkgName = pkg.packageName; 10855 10856 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 10857 final boolean dataDirExists = PackageManager.getDataDirForUser(volumeUuid, pkgName, 10858 UserHandle.USER_OWNER).exists(); 10859 synchronized(mPackages) { 10860 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 10861 // A package with the same name is already installed, though 10862 // it has been renamed to an older name. The package we 10863 // are trying to install should be installed as an update to 10864 // the existing one, but that has not been requested, so bail. 10865 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10866 + " without first uninstalling package running as " 10867 + mSettings.mRenamedPackages.get(pkgName)); 10868 return; 10869 } 10870 if (mPackages.containsKey(pkgName)) { 10871 // Don't allow installation over an existing package with the same name. 10872 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10873 + " without first uninstalling."); 10874 return; 10875 } 10876 } 10877 10878 try { 10879 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 10880 System.currentTimeMillis(), user); 10881 10882 updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user); 10883 // delete the partially installed application. the data directory will have to be 10884 // restored if it was already existing 10885 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10886 // remove package from internal structures. Note that we want deletePackageX to 10887 // delete the package data and cache directories that it created in 10888 // scanPackageLocked, unless those directories existed before we even tried to 10889 // install. 10890 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 10891 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 10892 res.removedInfo, true); 10893 } 10894 10895 } catch (PackageManagerException e) { 10896 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10897 } 10898 } 10899 10900 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 10901 // Upgrade keysets are being used. Determine if new package has a superset of the 10902 // required keys. 10903 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 10904 KeySetManagerService ksms = mSettings.mKeySetManagerService; 10905 for (int i = 0; i < upgradeKeySets.length; i++) { 10906 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 10907 if (newPkg.mSigningKeys.containsAll(upgradeSet)) { 10908 return true; 10909 } 10910 } 10911 return false; 10912 } 10913 10914 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 10915 UserHandle user, String installerPackageName, String volumeUuid, 10916 PackageInstalledInfo res) { 10917 final PackageParser.Package oldPackage; 10918 final String pkgName = pkg.packageName; 10919 final int[] allUsers; 10920 final boolean[] perUserInstalled; 10921 final boolean weFroze; 10922 10923 // First find the old package info and check signatures 10924 synchronized(mPackages) { 10925 oldPackage = mPackages.get(pkgName); 10926 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 10927 final PackageSetting ps = mSettings.mPackages.get(pkgName); 10928 if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 10929 // default to original signature matching 10930 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 10931 != PackageManager.SIGNATURE_MATCH) { 10932 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10933 "New package has a different signature: " + pkgName); 10934 return; 10935 } 10936 } else { 10937 if(!checkUpgradeKeySetLP(ps, pkg)) { 10938 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10939 "New package not signed by keys specified by upgrade-keysets: " 10940 + pkgName); 10941 return; 10942 } 10943 } 10944 10945 // In case of rollback, remember per-user/profile install state 10946 allUsers = sUserManager.getUserIds(); 10947 perUserInstalled = new boolean[allUsers.length]; 10948 for (int i = 0; i < allUsers.length; i++) { 10949 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 10950 } 10951 10952 // Mark the app as frozen to prevent launching during the upgrade 10953 // process, and then kill all running instances 10954 if (!ps.frozen) { 10955 ps.frozen = true; 10956 weFroze = true; 10957 } else { 10958 weFroze = false; 10959 } 10960 } 10961 10962 // Now that we're guarded by frozen state, kill app during upgrade 10963 killApplication(pkgName, oldPackage.applicationInfo.uid, "replace pkg"); 10964 10965 try { 10966 boolean sysPkg = (isSystemApp(oldPackage)); 10967 if (sysPkg) { 10968 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10969 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 10970 } else { 10971 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10972 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 10973 } 10974 } finally { 10975 // Regardless of success or failure of upgrade steps above, always 10976 // unfreeze the package if we froze it 10977 if (weFroze) { 10978 unfreezePackage(pkgName); 10979 } 10980 } 10981 } 10982 10983 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 10984 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 10985 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 10986 String volumeUuid, PackageInstalledInfo res) { 10987 String pkgName = deletedPackage.packageName; 10988 boolean deletedPkg = true; 10989 boolean updatedSettings = false; 10990 10991 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 10992 + deletedPackage); 10993 long origUpdateTime; 10994 if (pkg.mExtras != null) { 10995 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 10996 } else { 10997 origUpdateTime = 0; 10998 } 10999 11000 // First delete the existing package while retaining the data directory 11001 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 11002 res.removedInfo, true)) { 11003 // If the existing package wasn't successfully deleted 11004 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 11005 deletedPkg = false; 11006 } else { 11007 // Successfully deleted the old package; proceed with replace. 11008 11009 // If deleted package lived in a container, give users a chance to 11010 // relinquish resources before killing. 11011 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 11012 if (DEBUG_INSTALL) { 11013 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 11014 } 11015 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 11016 final ArrayList<String> pkgList = new ArrayList<String>(1); 11017 pkgList.add(deletedPackage.applicationInfo.packageName); 11018 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 11019 } 11020 11021 deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName); 11022 try { 11023 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, 11024 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 11025 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 11026 perUserInstalled, res, user); 11027 updatedSettings = true; 11028 } catch (PackageManagerException e) { 11029 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11030 } 11031 } 11032 11033 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11034 // remove package from internal structures. Note that we want deletePackageX to 11035 // delete the package data and cache directories that it created in 11036 // scanPackageLocked, unless those directories existed before we even tried to 11037 // install. 11038 if(updatedSettings) { 11039 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 11040 deletePackageLI( 11041 pkgName, null, true, allUsers, perUserInstalled, 11042 PackageManager.DELETE_KEEP_DATA, 11043 res.removedInfo, true); 11044 } 11045 // Since we failed to install the new package we need to restore the old 11046 // package that we deleted. 11047 if (deletedPkg) { 11048 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 11049 File restoreFile = new File(deletedPackage.codePath); 11050 // Parse old package 11051 boolean oldExternal = isExternal(deletedPackage); 11052 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 11053 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 11054 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 11055 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 11056 try { 11057 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null); 11058 } catch (PackageManagerException e) { 11059 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 11060 + e.getMessage()); 11061 return; 11062 } 11063 // Restore of old package succeeded. Update permissions. 11064 // writer 11065 synchronized (mPackages) { 11066 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 11067 UPDATE_PERMISSIONS_ALL); 11068 // can downgrade to reader 11069 mSettings.writeLPr(); 11070 } 11071 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 11072 } 11073 } 11074 } 11075 11076 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 11077 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 11078 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 11079 String volumeUuid, PackageInstalledInfo res) { 11080 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 11081 + ", old=" + deletedPackage); 11082 boolean disabledSystem = false; 11083 boolean updatedSettings = false; 11084 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 11085 if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 11086 != 0) { 11087 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 11088 } 11089 String packageName = deletedPackage.packageName; 11090 if (packageName == null) { 11091 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 11092 "Attempt to delete null packageName."); 11093 return; 11094 } 11095 PackageParser.Package oldPkg; 11096 PackageSetting oldPkgSetting; 11097 // reader 11098 synchronized (mPackages) { 11099 oldPkg = mPackages.get(packageName); 11100 oldPkgSetting = mSettings.mPackages.get(packageName); 11101 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 11102 (oldPkgSetting == null)) { 11103 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 11104 "Couldn't find package:" + packageName + " information"); 11105 return; 11106 } 11107 } 11108 11109 res.removedInfo.uid = oldPkg.applicationInfo.uid; 11110 res.removedInfo.removedPackage = packageName; 11111 // Remove existing system package 11112 removePackageLI(oldPkgSetting, true); 11113 // writer 11114 synchronized (mPackages) { 11115 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 11116 if (!disabledSystem && deletedPackage != null) { 11117 // We didn't need to disable the .apk as a current system package, 11118 // which means we are replacing another update that is already 11119 // installed. We need to make sure to delete the older one's .apk. 11120 res.removedInfo.args = createInstallArgsForExisting(0, 11121 deletedPackage.applicationInfo.getCodePath(), 11122 deletedPackage.applicationInfo.getResourcePath(), 11123 getAppDexInstructionSets(deletedPackage.applicationInfo)); 11124 } else { 11125 res.removedInfo.args = null; 11126 } 11127 } 11128 11129 // Successfully disabled the old package. Now proceed with re-installation 11130 deleteCodeCacheDirsLI(pkg.volumeUuid, packageName); 11131 11132 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11133 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 11134 11135 PackageParser.Package newPackage = null; 11136 try { 11137 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user); 11138 if (newPackage.mExtras != null) { 11139 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 11140 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 11141 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 11142 11143 // is the update attempting to change shared user? that isn't going to work... 11144 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 11145 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 11146 "Forbidding shared user change from " + oldPkgSetting.sharedUser 11147 + " to " + newPkgSetting.sharedUser); 11148 updatedSettings = true; 11149 } 11150 } 11151 11152 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11153 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 11154 perUserInstalled, res, user); 11155 updatedSettings = true; 11156 } 11157 11158 } catch (PackageManagerException e) { 11159 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11160 } 11161 11162 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11163 // Re installation failed. Restore old information 11164 // Remove new pkg information 11165 if (newPackage != null) { 11166 removeInstalledPackageLI(newPackage, true); 11167 } 11168 // Add back the old system package 11169 try { 11170 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 11171 } catch (PackageManagerException e) { 11172 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 11173 } 11174 // Restore the old system information in Settings 11175 synchronized (mPackages) { 11176 if (disabledSystem) { 11177 mSettings.enableSystemPackageLPw(packageName); 11178 } 11179 if (updatedSettings) { 11180 mSettings.setInstallerPackageName(packageName, 11181 oldPkgSetting.installerPackageName); 11182 } 11183 mSettings.writeLPr(); 11184 } 11185 } 11186 } 11187 11188 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 11189 String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, 11190 UserHandle user) { 11191 String pkgName = newPackage.packageName; 11192 synchronized (mPackages) { 11193 //write settings. the installStatus will be incomplete at this stage. 11194 //note that the new package setting would have already been 11195 //added to mPackages. It hasn't been persisted yet. 11196 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 11197 mSettings.writeLPr(); 11198 } 11199 11200 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 11201 11202 synchronized (mPackages) { 11203 updatePermissionsLPw(newPackage.packageName, newPackage, 11204 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 11205 ? UPDATE_PERMISSIONS_ALL : 0)); 11206 // For system-bundled packages, we assume that installing an upgraded version 11207 // of the package implies that the user actually wants to run that new code, 11208 // so we enable the package. 11209 PackageSetting ps = mSettings.mPackages.get(pkgName); 11210 if (ps != null) { 11211 if (isSystemApp(newPackage)) { 11212 // NB: implicit assumption that system package upgrades apply to all users 11213 if (DEBUG_INSTALL) { 11214 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 11215 } 11216 if (res.origUsers != null) { 11217 for (int userHandle : res.origUsers) { 11218 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 11219 userHandle, installerPackageName); 11220 } 11221 } 11222 // Also convey the prior install/uninstall state 11223 if (allUsers != null && perUserInstalled != null) { 11224 for (int i = 0; i < allUsers.length; i++) { 11225 if (DEBUG_INSTALL) { 11226 Slog.d(TAG, " user " + allUsers[i] 11227 + " => " + perUserInstalled[i]); 11228 } 11229 ps.setInstalled(perUserInstalled[i], allUsers[i]); 11230 } 11231 // these install state changes will be persisted in the 11232 // upcoming call to mSettings.writeLPr(). 11233 } 11234 } 11235 // It's implied that when a user requests installation, they want the app to be 11236 // installed and enabled. 11237 int userId = user.getIdentifier(); 11238 if (userId != UserHandle.USER_ALL) { 11239 ps.setInstalled(true, userId); 11240 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 11241 } 11242 } 11243 res.name = pkgName; 11244 res.uid = newPackage.applicationInfo.uid; 11245 res.pkg = newPackage; 11246 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 11247 mSettings.setInstallerPackageName(pkgName, installerPackageName); 11248 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11249 //to update install status 11250 mSettings.writeLPr(); 11251 } 11252 } 11253 11254 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 11255 final int installFlags = args.installFlags; 11256 final String installerPackageName = args.installerPackageName; 11257 final String volumeUuid = args.volumeUuid; 11258 final File tmpPackageFile = new File(args.getCodePath()); 11259 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 11260 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 11261 || (args.volumeUuid != null)); 11262 boolean replace = false; 11263 int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE; 11264 // Result object to be returned 11265 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11266 11267 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 11268 // Retrieve PackageSettings and parse package 11269 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 11270 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 11271 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 11272 PackageParser pp = new PackageParser(); 11273 pp.setSeparateProcesses(mSeparateProcesses); 11274 pp.setDisplayMetrics(mMetrics); 11275 11276 final PackageParser.Package pkg; 11277 try { 11278 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 11279 } catch (PackageParserException e) { 11280 res.setError("Failed parse during installPackageLI", e); 11281 return; 11282 } 11283 11284 // Mark that we have an install time CPU ABI override. 11285 pkg.cpuAbiOverride = args.abiOverride; 11286 11287 String pkgName = res.name = pkg.packageName; 11288 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 11289 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 11290 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 11291 return; 11292 } 11293 } 11294 11295 try { 11296 pp.collectCertificates(pkg, parseFlags); 11297 pp.collectManifestDigest(pkg); 11298 } catch (PackageParserException e) { 11299 res.setError("Failed collect during installPackageLI", e); 11300 return; 11301 } 11302 11303 /* If the installer passed in a manifest digest, compare it now. */ 11304 if (args.manifestDigest != null) { 11305 if (DEBUG_INSTALL) { 11306 final String parsedManifest = pkg.manifestDigest == null ? "null" 11307 : pkg.manifestDigest.toString(); 11308 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 11309 + parsedManifest); 11310 } 11311 11312 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 11313 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 11314 return; 11315 } 11316 } else if (DEBUG_INSTALL) { 11317 final String parsedManifest = pkg.manifestDigest == null 11318 ? "null" : pkg.manifestDigest.toString(); 11319 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 11320 } 11321 11322 // Get rid of all references to package scan path via parser. 11323 pp = null; 11324 String oldCodePath = null; 11325 boolean systemApp = false; 11326 synchronized (mPackages) { 11327 // Check if installing already existing package 11328 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11329 String oldName = mSettings.mRenamedPackages.get(pkgName); 11330 if (pkg.mOriginalPackages != null 11331 && pkg.mOriginalPackages.contains(oldName) 11332 && mPackages.containsKey(oldName)) { 11333 // This package is derived from an original package, 11334 // and this device has been updating from that original 11335 // name. We must continue using the original name, so 11336 // rename the new package here. 11337 pkg.setPackageName(oldName); 11338 pkgName = pkg.packageName; 11339 replace = true; 11340 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 11341 + oldName + " pkgName=" + pkgName); 11342 } else if (mPackages.containsKey(pkgName)) { 11343 // This package, under its official name, already exists 11344 // on the device; we should replace it. 11345 replace = true; 11346 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 11347 } 11348 } 11349 11350 PackageSetting ps = mSettings.mPackages.get(pkgName); 11351 if (ps != null) { 11352 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 11353 11354 // Quick sanity check that we're signed correctly if updating; 11355 // we'll check this again later when scanning, but we want to 11356 // bail early here before tripping over redefined permissions. 11357 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 11358 try { 11359 verifySignaturesLP(ps, pkg); 11360 } catch (PackageManagerException e) { 11361 res.setError(e.error, e.getMessage()); 11362 return; 11363 } 11364 } else { 11365 if (!checkUpgradeKeySetLP(ps, pkg)) { 11366 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 11367 + pkg.packageName + " upgrade keys do not match the " 11368 + "previously installed version"); 11369 return; 11370 } 11371 } 11372 11373 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 11374 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 11375 systemApp = (ps.pkg.applicationInfo.flags & 11376 ApplicationInfo.FLAG_SYSTEM) != 0; 11377 } 11378 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11379 } 11380 11381 // Check whether the newly-scanned package wants to define an already-defined perm 11382 int N = pkg.permissions.size(); 11383 for (int i = N-1; i >= 0; i--) { 11384 PackageParser.Permission perm = pkg.permissions.get(i); 11385 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 11386 if (bp != null) { 11387 // If the defining package is signed with our cert, it's okay. This 11388 // also includes the "updating the same package" case, of course. 11389 // "updating same package" could also involve key-rotation. 11390 final boolean sigsOk; 11391 if (!bp.sourcePackage.equals(pkg.packageName) 11392 || !(bp.packageSetting instanceof PackageSetting) 11393 || !bp.packageSetting.keySetData.isUsingUpgradeKeySets() 11394 || ((PackageSetting) bp.packageSetting).sharedUser != null) { 11395 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 11396 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 11397 } else { 11398 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 11399 } 11400 if (!sigsOk) { 11401 // If the owning package is the system itself, we log but allow 11402 // install to proceed; we fail the install on all other permission 11403 // redefinitions. 11404 if (!bp.sourcePackage.equals("android")) { 11405 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 11406 + pkg.packageName + " attempting to redeclare permission " 11407 + perm.info.name + " already owned by " + bp.sourcePackage); 11408 res.origPermission = perm.info.name; 11409 res.origPackage = bp.sourcePackage; 11410 return; 11411 } else { 11412 Slog.w(TAG, "Package " + pkg.packageName 11413 + " attempting to redeclare system permission " 11414 + perm.info.name + "; ignoring new declaration"); 11415 pkg.permissions.remove(i); 11416 } 11417 } 11418 } 11419 } 11420 11421 } 11422 11423 if (systemApp && onExternal) { 11424 // Disable updates to system apps on sdcard 11425 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 11426 "Cannot install updates to system apps on sdcard"); 11427 return; 11428 } 11429 11430 if (args.move != null) { 11431 // We did an in-place move, so dex is ready to roll 11432 scanFlags |= SCAN_NO_DEX; 11433 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 11434 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 11435 scanFlags |= SCAN_NO_DEX; 11436 // Run dexopt before old package gets removed, to minimize time when app is unavailable 11437 int result = mPackageDexOptimizer 11438 .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, 11439 false /* defer */, false /* inclDependencies */); 11440 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 11441 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); 11442 return; 11443 } 11444 } 11445 11446 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 11447 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 11448 return; 11449 } 11450 11451 startIntentFilterVerifications(args.user.getIdentifier(), pkg); 11452 11453 if (replace) { 11454 replacePackageLI(pkg, parseFlags, scanFlags, args.user, 11455 installerPackageName, volumeUuid, res); 11456 } else { 11457 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 11458 args.user, installerPackageName, volumeUuid, res); 11459 } 11460 synchronized (mPackages) { 11461 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11462 if (ps != null) { 11463 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11464 } 11465 } 11466 } 11467 11468 private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) { 11469 if (mIntentFilterVerifierComponent == null) { 11470 Slog.d(TAG, "No IntentFilter verification will not be done as " 11471 + "there is no IntentFilterVerifier available!"); 11472 return; 11473 } 11474 11475 final int verifierUid = getPackageUid( 11476 mIntentFilterVerifierComponent.getPackageName(), 11477 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId); 11478 11479 mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); 11480 final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 11481 msg.obj = pkg; 11482 msg.arg1 = userId; 11483 msg.arg2 = verifierUid; 11484 11485 mHandler.sendMessage(msg); 11486 } 11487 11488 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, 11489 PackageParser.Package pkg) { 11490 int size = pkg.activities.size(); 11491 if (size == 0) { 11492 Slog.d(TAG, "No activity, so no need to verify any IntentFilter!"); 11493 return; 11494 } 11495 11496 final boolean hasDomainURLs = hasDomainURLs(pkg); 11497 if (!hasDomainURLs) { 11498 Slog.d(TAG, "No domain URLs, so no need to verify any IntentFilter!"); 11499 return; 11500 } 11501 11502 Slog.d(TAG, "Checking for userId:" + userId + " if any IntentFilter from the " + size 11503 + " Activities needs verification ..."); 11504 11505 final int verificationId = mIntentFilterVerificationToken++; 11506 int count = 0; 11507 final String packageName = pkg.packageName; 11508 ArrayList<String> allHosts = new ArrayList<>(); 11509 11510 synchronized (mPackages) { 11511 for (PackageParser.Activity a : pkg.activities) { 11512 for (ActivityIntentInfo filter : a.intents) { 11513 boolean needsFilterVerification = filter.needsVerification(); 11514 if (needsFilterVerification && needsNetworkVerificationLPr(filter)) { 11515 Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); 11516 mIntentFilterVerifier.addOneIntentFilterVerification( 11517 verifierUid, userId, verificationId, filter, packageName); 11518 count++; 11519 } else if (!needsFilterVerification) { 11520 Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString()); 11521 if (hasValidDomains(filter)) { 11522 ArrayList<String> hosts = filter.getHostsList(); 11523 if (hosts.size() > 0) { 11524 allHosts.addAll(hosts); 11525 } else { 11526 if (allHosts.isEmpty()) { 11527 allHosts.add("*"); 11528 } 11529 } 11530 } 11531 } else { 11532 Slog.d(TAG, "Verification already done for IntentFilter:" 11533 + filter.toString()); 11534 } 11535 } 11536 } 11537 } 11538 11539 if (count > 0) { 11540 mIntentFilterVerifier.startVerifications(userId); 11541 Slog.d(TAG, "Started " + count + " IntentFilter verification" 11542 + (count > 1 ? "s" : "") + " for userId:" + userId + "!"); 11543 } else { 11544 Slog.d(TAG, "No need to start any IntentFilter verification!"); 11545 if (allHosts.size() > 0 && mSettings.createIntentFilterVerificationIfNeededLPw( 11546 packageName, allHosts) != null) { 11547 scheduleWriteSettingsLocked(); 11548 } 11549 } 11550 } 11551 11552 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 11553 final ComponentName cn = filter.activity.getComponentName(); 11554 final String packageName = cn.getPackageName(); 11555 11556 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 11557 packageName); 11558 if (ivi == null) { 11559 return true; 11560 } 11561 int status = ivi.getStatus(); 11562 switch (status) { 11563 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 11564 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 11565 return true; 11566 11567 default: 11568 // Nothing to do 11569 return false; 11570 } 11571 } 11572 11573 private static boolean isMultiArch(PackageSetting ps) { 11574 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11575 } 11576 11577 private static boolean isMultiArch(ApplicationInfo info) { 11578 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11579 } 11580 11581 private static boolean isExternal(PackageParser.Package pkg) { 11582 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11583 } 11584 11585 private static boolean isExternal(PackageSetting ps) { 11586 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11587 } 11588 11589 private static boolean isExternal(ApplicationInfo info) { 11590 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11591 } 11592 11593 private static boolean isSystemApp(PackageParser.Package pkg) { 11594 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11595 } 11596 11597 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 11598 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 11599 } 11600 11601 private static boolean hasDomainURLs(PackageParser.Package pkg) { 11602 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 11603 } 11604 11605 private static boolean isSystemApp(PackageSetting ps) { 11606 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 11607 } 11608 11609 private static boolean isUpdatedSystemApp(PackageSetting ps) { 11610 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 11611 } 11612 11613 private int packageFlagsToInstallFlags(PackageSetting ps) { 11614 int installFlags = 0; 11615 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 11616 // This existing package was an external ASEC install when we have 11617 // the external flag without a UUID 11618 installFlags |= PackageManager.INSTALL_EXTERNAL; 11619 } 11620 if (ps.isForwardLocked()) { 11621 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 11622 } 11623 return installFlags; 11624 } 11625 11626 private void deleteTempPackageFiles() { 11627 final FilenameFilter filter = new FilenameFilter() { 11628 public boolean accept(File dir, String name) { 11629 return name.startsWith("vmdl") && name.endsWith(".tmp"); 11630 } 11631 }; 11632 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 11633 file.delete(); 11634 } 11635 } 11636 11637 @Override 11638 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 11639 int flags) { 11640 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 11641 flags); 11642 } 11643 11644 @Override 11645 public void deletePackage(final String packageName, 11646 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 11647 mContext.enforceCallingOrSelfPermission( 11648 android.Manifest.permission.DELETE_PACKAGES, null); 11649 final int uid = Binder.getCallingUid(); 11650 if (UserHandle.getUserId(uid) != userId) { 11651 mContext.enforceCallingPermission( 11652 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11653 "deletePackage for user " + userId); 11654 } 11655 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 11656 try { 11657 observer.onPackageDeleted(packageName, 11658 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 11659 } catch (RemoteException re) { 11660 } 11661 return; 11662 } 11663 11664 boolean uninstallBlocked = false; 11665 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 11666 int[] users = sUserManager.getUserIds(); 11667 for (int i = 0; i < users.length; ++i) { 11668 if (getBlockUninstallForUser(packageName, users[i])) { 11669 uninstallBlocked = true; 11670 break; 11671 } 11672 } 11673 } else { 11674 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 11675 } 11676 if (uninstallBlocked) { 11677 try { 11678 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 11679 null); 11680 } catch (RemoteException re) { 11681 } 11682 return; 11683 } 11684 11685 if (DEBUG_REMOVE) { 11686 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 11687 } 11688 // Queue up an async operation since the package deletion may take a little while. 11689 mHandler.post(new Runnable() { 11690 public void run() { 11691 mHandler.removeCallbacks(this); 11692 final int returnCode = deletePackageX(packageName, userId, flags); 11693 if (observer != null) { 11694 try { 11695 observer.onPackageDeleted(packageName, returnCode, null); 11696 } catch (RemoteException e) { 11697 Log.i(TAG, "Observer no longer exists."); 11698 } //end catch 11699 } //end if 11700 } //end run 11701 }); 11702 } 11703 11704 private boolean isPackageDeviceAdmin(String packageName, int userId) { 11705 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 11706 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 11707 try { 11708 if (dpm != null) { 11709 if (dpm.isDeviceOwner(packageName)) { 11710 return true; 11711 } 11712 int[] users; 11713 if (userId == UserHandle.USER_ALL) { 11714 users = sUserManager.getUserIds(); 11715 } else { 11716 users = new int[]{userId}; 11717 } 11718 for (int i = 0; i < users.length; ++i) { 11719 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 11720 return true; 11721 } 11722 } 11723 } 11724 } catch (RemoteException e) { 11725 } 11726 return false; 11727 } 11728 11729 /** 11730 * This method is an internal method that could be get invoked either 11731 * to delete an installed package or to clean up a failed installation. 11732 * After deleting an installed package, a broadcast is sent to notify any 11733 * listeners that the package has been installed. For cleaning up a failed 11734 * installation, the broadcast is not necessary since the package's 11735 * installation wouldn't have sent the initial broadcast either 11736 * The key steps in deleting a package are 11737 * deleting the package information in internal structures like mPackages, 11738 * deleting the packages base directories through installd 11739 * updating mSettings to reflect current status 11740 * persisting settings for later use 11741 * sending a broadcast if necessary 11742 */ 11743 private int deletePackageX(String packageName, int userId, int flags) { 11744 final PackageRemovedInfo info = new PackageRemovedInfo(); 11745 final boolean res; 11746 11747 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 11748 ? UserHandle.ALL : new UserHandle(userId); 11749 11750 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 11751 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 11752 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 11753 } 11754 11755 boolean removedForAllUsers = false; 11756 boolean systemUpdate = false; 11757 11758 // for the uninstall-updates case and restricted profiles, remember the per- 11759 // userhandle installed state 11760 int[] allUsers; 11761 boolean[] perUserInstalled; 11762 synchronized (mPackages) { 11763 PackageSetting ps = mSettings.mPackages.get(packageName); 11764 allUsers = sUserManager.getUserIds(); 11765 perUserInstalled = new boolean[allUsers.length]; 11766 for (int i = 0; i < allUsers.length; i++) { 11767 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 11768 } 11769 } 11770 11771 synchronized (mInstallLock) { 11772 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 11773 res = deletePackageLI(packageName, removeForUser, 11774 true, allUsers, perUserInstalled, 11775 flags | REMOVE_CHATTY, info, true); 11776 systemUpdate = info.isRemovedPackageSystemUpdate; 11777 if (res && !systemUpdate && mPackages.get(packageName) == null) { 11778 removedForAllUsers = true; 11779 } 11780 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 11781 + " removedForAllUsers=" + removedForAllUsers); 11782 } 11783 11784 if (res) { 11785 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 11786 11787 // If the removed package was a system update, the old system package 11788 // was re-enabled; we need to broadcast this information 11789 if (systemUpdate) { 11790 Bundle extras = new Bundle(1); 11791 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 11792 ? info.removedAppId : info.uid); 11793 extras.putBoolean(Intent.EXTRA_REPLACING, true); 11794 11795 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 11796 extras, null, null, null); 11797 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 11798 extras, null, null, null); 11799 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 11800 null, packageName, null, null); 11801 } 11802 } 11803 // Force a gc here. 11804 Runtime.getRuntime().gc(); 11805 // Delete the resources here after sending the broadcast to let 11806 // other processes clean up before deleting resources. 11807 if (info.args != null) { 11808 synchronized (mInstallLock) { 11809 info.args.doPostDeleteLI(true); 11810 } 11811 } 11812 11813 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 11814 } 11815 11816 class PackageRemovedInfo { 11817 String removedPackage; 11818 int uid = -1; 11819 int removedAppId = -1; 11820 int[] removedUsers = null; 11821 boolean isRemovedPackageSystemUpdate = false; 11822 // Clean up resources deleted packages. 11823 InstallArgs args = null; 11824 11825 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 11826 Bundle extras = new Bundle(1); 11827 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 11828 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 11829 if (replacing) { 11830 extras.putBoolean(Intent.EXTRA_REPLACING, true); 11831 } 11832 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 11833 if (removedPackage != null) { 11834 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 11835 extras, null, null, removedUsers); 11836 if (fullRemove && !replacing) { 11837 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 11838 extras, null, null, removedUsers); 11839 } 11840 } 11841 if (removedAppId >= 0) { 11842 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 11843 removedUsers); 11844 } 11845 } 11846 } 11847 11848 /* 11849 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 11850 * flag is not set, the data directory is removed as well. 11851 * make sure this flag is set for partially installed apps. If not its meaningless to 11852 * delete a partially installed application. 11853 */ 11854 private void removePackageDataLI(PackageSetting ps, 11855 int[] allUserHandles, boolean[] perUserInstalled, 11856 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 11857 String packageName = ps.name; 11858 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 11859 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 11860 // Retrieve object to delete permissions for shared user later on 11861 final PackageSetting deletedPs; 11862 // reader 11863 synchronized (mPackages) { 11864 deletedPs = mSettings.mPackages.get(packageName); 11865 if (outInfo != null) { 11866 outInfo.removedPackage = packageName; 11867 outInfo.removedUsers = deletedPs != null 11868 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 11869 : null; 11870 } 11871 } 11872 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11873 removeDataDirsLI(ps.volumeUuid, packageName); 11874 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 11875 } 11876 // writer 11877 synchronized (mPackages) { 11878 if (deletedPs != null) { 11879 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11880 if (outInfo != null) { 11881 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 11882 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 11883 } 11884 updatePermissionsLPw(deletedPs.name, null, 0); 11885 if (deletedPs.sharedUser != null) { 11886 // Remove permissions associated with package. Since runtime 11887 // permissions are per user we have to kill the removed package 11888 // or packages running under the shared user of the removed 11889 // package if revoking the permissions requested only by the removed 11890 // package is successful and this causes a change in gids. 11891 for (int userId : UserManagerService.getInstance().getUserIds()) { 11892 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 11893 userId); 11894 if (userIdToKill == UserHandle.USER_ALL 11895 || userIdToKill >= UserHandle.USER_OWNER) { 11896 // If gids changed for this user, kill all affected packages. 11897 mHandler.post(new Runnable() { 11898 @Override 11899 public void run() { 11900 // This has to happen with no lock held. 11901 killSettingPackagesForUser(deletedPs, userIdToKill, 11902 KILL_APP_REASON_GIDS_CHANGED); 11903 } 11904 }); 11905 break; 11906 } 11907 } 11908 } 11909 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 11910 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 11911 } 11912 // make sure to preserve per-user disabled state if this removal was just 11913 // a downgrade of a system app to the factory package 11914 if (allUserHandles != null && perUserInstalled != null) { 11915 if (DEBUG_REMOVE) { 11916 Slog.d(TAG, "Propagating install state across downgrade"); 11917 } 11918 for (int i = 0; i < allUserHandles.length; i++) { 11919 if (DEBUG_REMOVE) { 11920 Slog.d(TAG, " user " + allUserHandles[i] 11921 + " => " + perUserInstalled[i]); 11922 } 11923 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 11924 } 11925 } 11926 } 11927 // can downgrade to reader 11928 if (writeSettings) { 11929 // Save settings now 11930 mSettings.writeLPr(); 11931 } 11932 } 11933 if (outInfo != null) { 11934 // A user ID was deleted here. Go through all users and remove it 11935 // from KeyStore. 11936 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 11937 } 11938 } 11939 11940 static boolean locationIsPrivileged(File path) { 11941 try { 11942 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 11943 .getCanonicalPath(); 11944 return path.getCanonicalPath().startsWith(privilegedAppDir); 11945 } catch (IOException e) { 11946 Slog.e(TAG, "Unable to access code path " + path); 11947 } 11948 return false; 11949 } 11950 11951 /* 11952 * Tries to delete system package. 11953 */ 11954 private boolean deleteSystemPackageLI(PackageSetting newPs, 11955 int[] allUserHandles, boolean[] perUserInstalled, 11956 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 11957 final boolean applyUserRestrictions 11958 = (allUserHandles != null) && (perUserInstalled != null); 11959 PackageSetting disabledPs = null; 11960 // Confirm if the system package has been updated 11961 // An updated system app can be deleted. This will also have to restore 11962 // the system pkg from system partition 11963 // reader 11964 synchronized (mPackages) { 11965 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 11966 } 11967 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 11968 + " disabledPs=" + disabledPs); 11969 if (disabledPs == null) { 11970 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 11971 return false; 11972 } else if (DEBUG_REMOVE) { 11973 Slog.d(TAG, "Deleting system pkg from data partition"); 11974 } 11975 if (DEBUG_REMOVE) { 11976 if (applyUserRestrictions) { 11977 Slog.d(TAG, "Remembering install states:"); 11978 for (int i = 0; i < allUserHandles.length; i++) { 11979 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 11980 } 11981 } 11982 } 11983 // Delete the updated package 11984 outInfo.isRemovedPackageSystemUpdate = true; 11985 if (disabledPs.versionCode < newPs.versionCode) { 11986 // Delete data for downgrades 11987 flags &= ~PackageManager.DELETE_KEEP_DATA; 11988 } else { 11989 // Preserve data by setting flag 11990 flags |= PackageManager.DELETE_KEEP_DATA; 11991 } 11992 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 11993 allUserHandles, perUserInstalled, outInfo, writeSettings); 11994 if (!ret) { 11995 return false; 11996 } 11997 // writer 11998 synchronized (mPackages) { 11999 // Reinstate the old system package 12000 mSettings.enableSystemPackageLPw(newPs.name); 12001 // Remove any native libraries from the upgraded package. 12002 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 12003 } 12004 // Install the system package 12005 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 12006 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 12007 if (locationIsPrivileged(disabledPs.codePath)) { 12008 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 12009 } 12010 12011 final PackageParser.Package newPkg; 12012 try { 12013 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 12014 } catch (PackageManagerException e) { 12015 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 12016 return false; 12017 } 12018 12019 // writer 12020 synchronized (mPackages) { 12021 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 12022 updatePermissionsLPw(newPkg.packageName, newPkg, 12023 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 12024 if (applyUserRestrictions) { 12025 if (DEBUG_REMOVE) { 12026 Slog.d(TAG, "Propagating install state across reinstall"); 12027 } 12028 for (int i = 0; i < allUserHandles.length; i++) { 12029 if (DEBUG_REMOVE) { 12030 Slog.d(TAG, " user " + allUserHandles[i] 12031 + " => " + perUserInstalled[i]); 12032 } 12033 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 12034 } 12035 // Regardless of writeSettings we need to ensure that this restriction 12036 // state propagation is persisted 12037 mSettings.writeAllUsersPackageRestrictionsLPr(); 12038 } 12039 // can downgrade to reader here 12040 if (writeSettings) { 12041 mSettings.writeLPr(); 12042 } 12043 } 12044 return true; 12045 } 12046 12047 private boolean deleteInstalledPackageLI(PackageSetting ps, 12048 boolean deleteCodeAndResources, int flags, 12049 int[] allUserHandles, boolean[] perUserInstalled, 12050 PackageRemovedInfo outInfo, boolean writeSettings) { 12051 if (outInfo != null) { 12052 outInfo.uid = ps.appId; 12053 } 12054 12055 // Delete package data from internal structures and also remove data if flag is set 12056 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 12057 12058 // Delete application code and resources 12059 if (deleteCodeAndResources && (outInfo != null)) { 12060 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 12061 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 12062 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 12063 } 12064 return true; 12065 } 12066 12067 @Override 12068 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 12069 int userId) { 12070 mContext.enforceCallingOrSelfPermission( 12071 android.Manifest.permission.DELETE_PACKAGES, null); 12072 synchronized (mPackages) { 12073 PackageSetting ps = mSettings.mPackages.get(packageName); 12074 if (ps == null) { 12075 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 12076 return false; 12077 } 12078 if (!ps.getInstalled(userId)) { 12079 // Can't block uninstall for an app that is not installed or enabled. 12080 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 12081 return false; 12082 } 12083 ps.setBlockUninstall(blockUninstall, userId); 12084 mSettings.writePackageRestrictionsLPr(userId); 12085 } 12086 return true; 12087 } 12088 12089 @Override 12090 public boolean getBlockUninstallForUser(String packageName, int userId) { 12091 synchronized (mPackages) { 12092 PackageSetting ps = mSettings.mPackages.get(packageName); 12093 if (ps == null) { 12094 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 12095 return false; 12096 } 12097 return ps.getBlockUninstall(userId); 12098 } 12099 } 12100 12101 /* 12102 * This method handles package deletion in general 12103 */ 12104 private boolean deletePackageLI(String packageName, UserHandle user, 12105 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 12106 int flags, PackageRemovedInfo outInfo, 12107 boolean writeSettings) { 12108 if (packageName == null) { 12109 Slog.w(TAG, "Attempt to delete null packageName."); 12110 return false; 12111 } 12112 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 12113 PackageSetting ps; 12114 boolean dataOnly = false; 12115 int removeUser = -1; 12116 int appId = -1; 12117 synchronized (mPackages) { 12118 ps = mSettings.mPackages.get(packageName); 12119 if (ps == null) { 12120 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 12121 return false; 12122 } 12123 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 12124 && user.getIdentifier() != UserHandle.USER_ALL) { 12125 // The caller is asking that the package only be deleted for a single 12126 // user. To do this, we just mark its uninstalled state and delete 12127 // its data. If this is a system app, we only allow this to happen if 12128 // they have set the special DELETE_SYSTEM_APP which requests different 12129 // semantics than normal for uninstalling system apps. 12130 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 12131 ps.setUserState(user.getIdentifier(), 12132 COMPONENT_ENABLED_STATE_DEFAULT, 12133 false, //installed 12134 true, //stopped 12135 true, //notLaunched 12136 false, //hidden 12137 null, null, null, 12138 false, // blockUninstall 12139 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 12140 if (!isSystemApp(ps)) { 12141 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 12142 // Other user still have this package installed, so all 12143 // we need to do is clear this user's data and save that 12144 // it is uninstalled. 12145 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 12146 removeUser = user.getIdentifier(); 12147 appId = ps.appId; 12148 scheduleWritePackageRestrictionsLocked(removeUser); 12149 } else { 12150 // We need to set it back to 'installed' so the uninstall 12151 // broadcasts will be sent correctly. 12152 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 12153 ps.setInstalled(true, user.getIdentifier()); 12154 } 12155 } else { 12156 // This is a system app, so we assume that the 12157 // other users still have this package installed, so all 12158 // we need to do is clear this user's data and save that 12159 // it is uninstalled. 12160 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 12161 removeUser = user.getIdentifier(); 12162 appId = ps.appId; 12163 scheduleWritePackageRestrictionsLocked(removeUser); 12164 } 12165 } 12166 } 12167 12168 if (removeUser >= 0) { 12169 // From above, we determined that we are deleting this only 12170 // for a single user. Continue the work here. 12171 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 12172 if (outInfo != null) { 12173 outInfo.removedPackage = packageName; 12174 outInfo.removedAppId = appId; 12175 outInfo.removedUsers = new int[] {removeUser}; 12176 } 12177 mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser); 12178 removeKeystoreDataIfNeeded(removeUser, appId); 12179 schedulePackageCleaning(packageName, removeUser, false); 12180 synchronized (mPackages) { 12181 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { 12182 scheduleWritePackageRestrictionsLocked(removeUser); 12183 } 12184 } 12185 return true; 12186 } 12187 12188 if (dataOnly) { 12189 // Delete application data first 12190 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 12191 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 12192 return true; 12193 } 12194 12195 boolean ret = false; 12196 if (isSystemApp(ps)) { 12197 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 12198 // When an updated system application is deleted we delete the existing resources as well and 12199 // fall back to existing code in system partition 12200 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 12201 flags, outInfo, writeSettings); 12202 } else { 12203 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 12204 // Kill application pre-emptively especially for apps on sd. 12205 killApplication(packageName, ps.appId, "uninstall pkg"); 12206 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 12207 allUserHandles, perUserInstalled, 12208 outInfo, writeSettings); 12209 } 12210 12211 return ret; 12212 } 12213 12214 private final class ClearStorageConnection implements ServiceConnection { 12215 IMediaContainerService mContainerService; 12216 12217 @Override 12218 public void onServiceConnected(ComponentName name, IBinder service) { 12219 synchronized (this) { 12220 mContainerService = IMediaContainerService.Stub.asInterface(service); 12221 notifyAll(); 12222 } 12223 } 12224 12225 @Override 12226 public void onServiceDisconnected(ComponentName name) { 12227 } 12228 } 12229 12230 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 12231 final boolean mounted; 12232 if (Environment.isExternalStorageEmulated()) { 12233 mounted = true; 12234 } else { 12235 final String status = Environment.getExternalStorageState(); 12236 12237 mounted = status.equals(Environment.MEDIA_MOUNTED) 12238 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 12239 } 12240 12241 if (!mounted) { 12242 return; 12243 } 12244 12245 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 12246 int[] users; 12247 if (userId == UserHandle.USER_ALL) { 12248 users = sUserManager.getUserIds(); 12249 } else { 12250 users = new int[] { userId }; 12251 } 12252 final ClearStorageConnection conn = new ClearStorageConnection(); 12253 if (mContext.bindServiceAsUser( 12254 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 12255 try { 12256 for (int curUser : users) { 12257 long timeout = SystemClock.uptimeMillis() + 5000; 12258 synchronized (conn) { 12259 long now = SystemClock.uptimeMillis(); 12260 while (conn.mContainerService == null && now < timeout) { 12261 try { 12262 conn.wait(timeout - now); 12263 } catch (InterruptedException e) { 12264 } 12265 } 12266 } 12267 if (conn.mContainerService == null) { 12268 return; 12269 } 12270 12271 final UserEnvironment userEnv = new UserEnvironment(curUser); 12272 clearDirectory(conn.mContainerService, 12273 userEnv.buildExternalStorageAppCacheDirs(packageName)); 12274 if (allData) { 12275 clearDirectory(conn.mContainerService, 12276 userEnv.buildExternalStorageAppDataDirs(packageName)); 12277 clearDirectory(conn.mContainerService, 12278 userEnv.buildExternalStorageAppMediaDirs(packageName)); 12279 } 12280 } 12281 } finally { 12282 mContext.unbindService(conn); 12283 } 12284 } 12285 } 12286 12287 @Override 12288 public void clearApplicationUserData(final String packageName, 12289 final IPackageDataObserver observer, final int userId) { 12290 mContext.enforceCallingOrSelfPermission( 12291 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 12292 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 12293 // Queue up an async operation since the package deletion may take a little while. 12294 mHandler.post(new Runnable() { 12295 public void run() { 12296 mHandler.removeCallbacks(this); 12297 final boolean succeeded; 12298 synchronized (mInstallLock) { 12299 succeeded = clearApplicationUserDataLI(packageName, userId); 12300 } 12301 clearExternalStorageDataSync(packageName, userId, true); 12302 if (succeeded) { 12303 // invoke DeviceStorageMonitor's update method to clear any notifications 12304 DeviceStorageMonitorInternal 12305 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 12306 if (dsm != null) { 12307 dsm.checkMemory(); 12308 } 12309 } 12310 if(observer != null) { 12311 try { 12312 observer.onRemoveCompleted(packageName, succeeded); 12313 } catch (RemoteException e) { 12314 Log.i(TAG, "Observer no longer exists."); 12315 } 12316 } //end if observer 12317 } //end run 12318 }); 12319 } 12320 12321 private boolean clearApplicationUserDataLI(String packageName, int userId) { 12322 if (packageName == null) { 12323 Slog.w(TAG, "Attempt to delete null packageName."); 12324 return false; 12325 } 12326 12327 // Try finding details about the requested package 12328 PackageParser.Package pkg; 12329 synchronized (mPackages) { 12330 pkg = mPackages.get(packageName); 12331 if (pkg == null) { 12332 final PackageSetting ps = mSettings.mPackages.get(packageName); 12333 if (ps != null) { 12334 pkg = ps.pkg; 12335 } 12336 } 12337 } 12338 12339 if (pkg == null) { 12340 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 12341 } 12342 12343 // Always delete data directories for package, even if we found no other 12344 // record of app. This helps users recover from UID mismatches without 12345 // resorting to a full data wipe. 12346 int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId); 12347 if (retCode < 0) { 12348 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 12349 return false; 12350 } 12351 12352 if (pkg == null) { 12353 return false; 12354 } 12355 12356 if (pkg != null && pkg.applicationInfo != null) { 12357 final int appId = pkg.applicationInfo.uid; 12358 removeKeystoreDataIfNeeded(userId, appId); 12359 } 12360 12361 // Create a native library symlink only if we have native libraries 12362 // and if the native libraries are 32 bit libraries. We do not provide 12363 // this symlink for 64 bit libraries. 12364 if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null && 12365 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 12366 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 12367 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 12368 nativeLibPath, userId) < 0) { 12369 Slog.w(TAG, "Failed linking native library dir"); 12370 return false; 12371 } 12372 } 12373 12374 return true; 12375 } 12376 12377 /** 12378 * Remove entries from the keystore daemon. Will only remove it if the 12379 * {@code appId} is valid. 12380 */ 12381 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 12382 if (appId < 0) { 12383 return; 12384 } 12385 12386 final KeyStore keyStore = KeyStore.getInstance(); 12387 if (keyStore != null) { 12388 if (userId == UserHandle.USER_ALL) { 12389 for (final int individual : sUserManager.getUserIds()) { 12390 keyStore.clearUid(UserHandle.getUid(individual, appId)); 12391 } 12392 } else { 12393 keyStore.clearUid(UserHandle.getUid(userId, appId)); 12394 } 12395 } else { 12396 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 12397 } 12398 } 12399 12400 @Override 12401 public void deleteApplicationCacheFiles(final String packageName, 12402 final IPackageDataObserver observer) { 12403 mContext.enforceCallingOrSelfPermission( 12404 android.Manifest.permission.DELETE_CACHE_FILES, null); 12405 // Queue up an async operation since the package deletion may take a little while. 12406 final int userId = UserHandle.getCallingUserId(); 12407 mHandler.post(new Runnable() { 12408 public void run() { 12409 mHandler.removeCallbacks(this); 12410 final boolean succeded; 12411 synchronized (mInstallLock) { 12412 succeded = deleteApplicationCacheFilesLI(packageName, userId); 12413 } 12414 clearExternalStorageDataSync(packageName, userId, false); 12415 if(observer != null) { 12416 try { 12417 observer.onRemoveCompleted(packageName, succeded); 12418 } catch (RemoteException e) { 12419 Log.i(TAG, "Observer no longer exists."); 12420 } 12421 } //end if observer 12422 } //end run 12423 }); 12424 } 12425 12426 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 12427 if (packageName == null) { 12428 Slog.w(TAG, "Attempt to delete null packageName."); 12429 return false; 12430 } 12431 PackageParser.Package p; 12432 synchronized (mPackages) { 12433 p = mPackages.get(packageName); 12434 } 12435 if (p == null) { 12436 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12437 return false; 12438 } 12439 final ApplicationInfo applicationInfo = p.applicationInfo; 12440 if (applicationInfo == null) { 12441 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12442 return false; 12443 } 12444 int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId); 12445 if (retCode < 0) { 12446 Slog.w(TAG, "Couldn't remove cache files for package: " 12447 + packageName + " u" + userId); 12448 return false; 12449 } 12450 return true; 12451 } 12452 12453 @Override 12454 public void getPackageSizeInfo(final String packageName, int userHandle, 12455 final IPackageStatsObserver observer) { 12456 mContext.enforceCallingOrSelfPermission( 12457 android.Manifest.permission.GET_PACKAGE_SIZE, null); 12458 if (packageName == null) { 12459 throw new IllegalArgumentException("Attempt to get size of null packageName"); 12460 } 12461 12462 PackageStats stats = new PackageStats(packageName, userHandle); 12463 12464 /* 12465 * Queue up an async operation since the package measurement may take a 12466 * little while. 12467 */ 12468 Message msg = mHandler.obtainMessage(INIT_COPY); 12469 msg.obj = new MeasureParams(stats, observer); 12470 mHandler.sendMessage(msg); 12471 } 12472 12473 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 12474 PackageStats pStats) { 12475 if (packageName == null) { 12476 Slog.w(TAG, "Attempt to get size of null packageName."); 12477 return false; 12478 } 12479 PackageParser.Package p; 12480 boolean dataOnly = false; 12481 String libDirRoot = null; 12482 String asecPath = null; 12483 PackageSetting ps = null; 12484 synchronized (mPackages) { 12485 p = mPackages.get(packageName); 12486 ps = mSettings.mPackages.get(packageName); 12487 if(p == null) { 12488 dataOnly = true; 12489 if((ps == null) || (ps.pkg == null)) { 12490 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12491 return false; 12492 } 12493 p = ps.pkg; 12494 } 12495 if (ps != null) { 12496 libDirRoot = ps.legacyNativeLibraryPathString; 12497 } 12498 if (p != null && (isExternal(p) || p.isForwardLocked())) { 12499 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 12500 if (secureContainerId != null) { 12501 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 12502 } 12503 } 12504 } 12505 String publicSrcDir = null; 12506 if(!dataOnly) { 12507 final ApplicationInfo applicationInfo = p.applicationInfo; 12508 if (applicationInfo == null) { 12509 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12510 return false; 12511 } 12512 if (p.isForwardLocked()) { 12513 publicSrcDir = applicationInfo.getBaseResourcePath(); 12514 } 12515 } 12516 // TODO: extend to measure size of split APKs 12517 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 12518 // not just the first level. 12519 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 12520 // just the primary. 12521 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 12522 int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath, 12523 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 12524 if (res < 0) { 12525 return false; 12526 } 12527 12528 // Fix-up for forward-locked applications in ASEC containers. 12529 if (!isExternal(p)) { 12530 pStats.codeSize += pStats.externalCodeSize; 12531 pStats.externalCodeSize = 0L; 12532 } 12533 12534 return true; 12535 } 12536 12537 12538 @Override 12539 public void addPackageToPreferred(String packageName) { 12540 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 12541 } 12542 12543 @Override 12544 public void removePackageFromPreferred(String packageName) { 12545 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 12546 } 12547 12548 @Override 12549 public List<PackageInfo> getPreferredPackages(int flags) { 12550 return new ArrayList<PackageInfo>(); 12551 } 12552 12553 private int getUidTargetSdkVersionLockedLPr(int uid) { 12554 Object obj = mSettings.getUserIdLPr(uid); 12555 if (obj instanceof SharedUserSetting) { 12556 final SharedUserSetting sus = (SharedUserSetting) obj; 12557 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 12558 final Iterator<PackageSetting> it = sus.packages.iterator(); 12559 while (it.hasNext()) { 12560 final PackageSetting ps = it.next(); 12561 if (ps.pkg != null) { 12562 int v = ps.pkg.applicationInfo.targetSdkVersion; 12563 if (v < vers) vers = v; 12564 } 12565 } 12566 return vers; 12567 } else if (obj instanceof PackageSetting) { 12568 final PackageSetting ps = (PackageSetting) obj; 12569 if (ps.pkg != null) { 12570 return ps.pkg.applicationInfo.targetSdkVersion; 12571 } 12572 } 12573 return Build.VERSION_CODES.CUR_DEVELOPMENT; 12574 } 12575 12576 @Override 12577 public void addPreferredActivity(IntentFilter filter, int match, 12578 ComponentName[] set, ComponentName activity, int userId) { 12579 addPreferredActivityInternal(filter, match, set, activity, true, userId, 12580 "Adding preferred"); 12581 } 12582 12583 private void addPreferredActivityInternal(IntentFilter filter, int match, 12584 ComponentName[] set, ComponentName activity, boolean always, int userId, 12585 String opname) { 12586 // writer 12587 int callingUid = Binder.getCallingUid(); 12588 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 12589 if (filter.countActions() == 0) { 12590 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 12591 return; 12592 } 12593 synchronized (mPackages) { 12594 if (mContext.checkCallingOrSelfPermission( 12595 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12596 != PackageManager.PERMISSION_GRANTED) { 12597 if (getUidTargetSdkVersionLockedLPr(callingUid) 12598 < Build.VERSION_CODES.FROYO) { 12599 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 12600 + callingUid); 12601 return; 12602 } 12603 mContext.enforceCallingOrSelfPermission( 12604 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12605 } 12606 12607 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 12608 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 12609 + userId + ":"); 12610 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12611 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 12612 scheduleWritePackageRestrictionsLocked(userId); 12613 } 12614 } 12615 12616 @Override 12617 public void replacePreferredActivity(IntentFilter filter, int match, 12618 ComponentName[] set, ComponentName activity, int userId) { 12619 if (filter.countActions() != 1) { 12620 throw new IllegalArgumentException( 12621 "replacePreferredActivity expects filter to have only 1 action."); 12622 } 12623 if (filter.countDataAuthorities() != 0 12624 || filter.countDataPaths() != 0 12625 || filter.countDataSchemes() > 1 12626 || filter.countDataTypes() != 0) { 12627 throw new IllegalArgumentException( 12628 "replacePreferredActivity expects filter to have no data authorities, " + 12629 "paths, or types; and at most one scheme."); 12630 } 12631 12632 final int callingUid = Binder.getCallingUid(); 12633 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 12634 synchronized (mPackages) { 12635 if (mContext.checkCallingOrSelfPermission( 12636 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12637 != PackageManager.PERMISSION_GRANTED) { 12638 if (getUidTargetSdkVersionLockedLPr(callingUid) 12639 < Build.VERSION_CODES.FROYO) { 12640 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 12641 + Binder.getCallingUid()); 12642 return; 12643 } 12644 mContext.enforceCallingOrSelfPermission( 12645 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12646 } 12647 12648 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 12649 if (pir != null) { 12650 // Get all of the existing entries that exactly match this filter. 12651 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 12652 if (existing != null && existing.size() == 1) { 12653 PreferredActivity cur = existing.get(0); 12654 if (DEBUG_PREFERRED) { 12655 Slog.i(TAG, "Checking replace of preferred:"); 12656 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12657 if (!cur.mPref.mAlways) { 12658 Slog.i(TAG, " -- CUR; not mAlways!"); 12659 } else { 12660 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 12661 Slog.i(TAG, " -- CUR: mSet=" 12662 + Arrays.toString(cur.mPref.mSetComponents)); 12663 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 12664 Slog.i(TAG, " -- NEW: mMatch=" 12665 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 12666 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 12667 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 12668 } 12669 } 12670 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 12671 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 12672 && cur.mPref.sameSet(set)) { 12673 // Setting the preferred activity to what it happens to be already 12674 if (DEBUG_PREFERRED) { 12675 Slog.i(TAG, "Replacing with same preferred activity " 12676 + cur.mPref.mShortComponent + " for user " 12677 + userId + ":"); 12678 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12679 } 12680 return; 12681 } 12682 } 12683 12684 if (existing != null) { 12685 if (DEBUG_PREFERRED) { 12686 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 12687 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12688 } 12689 for (int i = 0; i < existing.size(); i++) { 12690 PreferredActivity pa = existing.get(i); 12691 if (DEBUG_PREFERRED) { 12692 Slog.i(TAG, "Removing existing preferred activity " 12693 + pa.mPref.mComponent + ":"); 12694 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 12695 } 12696 pir.removeFilter(pa); 12697 } 12698 } 12699 } 12700 addPreferredActivityInternal(filter, match, set, activity, true, userId, 12701 "Replacing preferred"); 12702 } 12703 } 12704 12705 @Override 12706 public void clearPackagePreferredActivities(String packageName) { 12707 final int uid = Binder.getCallingUid(); 12708 // writer 12709 synchronized (mPackages) { 12710 PackageParser.Package pkg = mPackages.get(packageName); 12711 if (pkg == null || pkg.applicationInfo.uid != uid) { 12712 if (mContext.checkCallingOrSelfPermission( 12713 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12714 != PackageManager.PERMISSION_GRANTED) { 12715 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 12716 < Build.VERSION_CODES.FROYO) { 12717 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 12718 + Binder.getCallingUid()); 12719 return; 12720 } 12721 mContext.enforceCallingOrSelfPermission( 12722 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12723 } 12724 } 12725 12726 int user = UserHandle.getCallingUserId(); 12727 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 12728 scheduleWritePackageRestrictionsLocked(user); 12729 } 12730 } 12731 } 12732 12733 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 12734 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 12735 ArrayList<PreferredActivity> removed = null; 12736 boolean changed = false; 12737 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 12738 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 12739 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 12740 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 12741 continue; 12742 } 12743 Iterator<PreferredActivity> it = pir.filterIterator(); 12744 while (it.hasNext()) { 12745 PreferredActivity pa = it.next(); 12746 // Mark entry for removal only if it matches the package name 12747 // and the entry is of type "always". 12748 if (packageName == null || 12749 (pa.mPref.mComponent.getPackageName().equals(packageName) 12750 && pa.mPref.mAlways)) { 12751 if (removed == null) { 12752 removed = new ArrayList<PreferredActivity>(); 12753 } 12754 removed.add(pa); 12755 } 12756 } 12757 if (removed != null) { 12758 for (int j=0; j<removed.size(); j++) { 12759 PreferredActivity pa = removed.get(j); 12760 pir.removeFilter(pa); 12761 } 12762 changed = true; 12763 } 12764 } 12765 return changed; 12766 } 12767 12768 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 12769 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 12770 if (userId == UserHandle.USER_ALL) { 12771 mSettings.removeIntentFilterVerificationLPw(packageName, sUserManager.getUserIds()); 12772 for (int oneUserId : sUserManager.getUserIds()) { 12773 scheduleWritePackageRestrictionsLocked(oneUserId); 12774 } 12775 } else { 12776 mSettings.removeIntentFilterVerificationLPw(packageName, userId); 12777 scheduleWritePackageRestrictionsLocked(userId); 12778 } 12779 } 12780 12781 @Override 12782 public void resetPreferredActivities(int userId) { 12783 /* TODO: Actually use userId. Why is it being passed in? */ 12784 mContext.enforceCallingOrSelfPermission( 12785 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12786 // writer 12787 synchronized (mPackages) { 12788 int user = UserHandle.getCallingUserId(); 12789 clearPackagePreferredActivitiesLPw(null, user); 12790 mSettings.readDefaultPreferredAppsLPw(this, user); 12791 scheduleWritePackageRestrictionsLocked(user); 12792 } 12793 } 12794 12795 @Override 12796 public int getPreferredActivities(List<IntentFilter> outFilters, 12797 List<ComponentName> outActivities, String packageName) { 12798 12799 int num = 0; 12800 final int userId = UserHandle.getCallingUserId(); 12801 // reader 12802 synchronized (mPackages) { 12803 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 12804 if (pir != null) { 12805 final Iterator<PreferredActivity> it = pir.filterIterator(); 12806 while (it.hasNext()) { 12807 final PreferredActivity pa = it.next(); 12808 if (packageName == null 12809 || (pa.mPref.mComponent.getPackageName().equals(packageName) 12810 && pa.mPref.mAlways)) { 12811 if (outFilters != null) { 12812 outFilters.add(new IntentFilter(pa)); 12813 } 12814 if (outActivities != null) { 12815 outActivities.add(pa.mPref.mComponent); 12816 } 12817 } 12818 } 12819 } 12820 } 12821 12822 return num; 12823 } 12824 12825 @Override 12826 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 12827 int userId) { 12828 int callingUid = Binder.getCallingUid(); 12829 if (callingUid != Process.SYSTEM_UID) { 12830 throw new SecurityException( 12831 "addPersistentPreferredActivity can only be run by the system"); 12832 } 12833 if (filter.countActions() == 0) { 12834 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 12835 return; 12836 } 12837 synchronized (mPackages) { 12838 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 12839 " :"); 12840 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12841 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 12842 new PersistentPreferredActivity(filter, activity)); 12843 scheduleWritePackageRestrictionsLocked(userId); 12844 } 12845 } 12846 12847 @Override 12848 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 12849 int callingUid = Binder.getCallingUid(); 12850 if (callingUid != Process.SYSTEM_UID) { 12851 throw new SecurityException( 12852 "clearPackagePersistentPreferredActivities can only be run by the system"); 12853 } 12854 ArrayList<PersistentPreferredActivity> removed = null; 12855 boolean changed = false; 12856 synchronized (mPackages) { 12857 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 12858 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 12859 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 12860 .valueAt(i); 12861 if (userId != thisUserId) { 12862 continue; 12863 } 12864 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 12865 while (it.hasNext()) { 12866 PersistentPreferredActivity ppa = it.next(); 12867 // Mark entry for removal only if it matches the package name. 12868 if (ppa.mComponent.getPackageName().equals(packageName)) { 12869 if (removed == null) { 12870 removed = new ArrayList<PersistentPreferredActivity>(); 12871 } 12872 removed.add(ppa); 12873 } 12874 } 12875 if (removed != null) { 12876 for (int j=0; j<removed.size(); j++) { 12877 PersistentPreferredActivity ppa = removed.get(j); 12878 ppir.removeFilter(ppa); 12879 } 12880 changed = true; 12881 } 12882 } 12883 12884 if (changed) { 12885 scheduleWritePackageRestrictionsLocked(userId); 12886 } 12887 } 12888 } 12889 12890 /** 12891 * Non-Binder method, support for the backup/restore mechanism: write the 12892 * full set of preferred activities in its canonical XML format. Returns true 12893 * on success; false otherwise. 12894 */ 12895 @Override 12896 public byte[] getPreferredActivityBackup(int userId) { 12897 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12898 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 12899 } 12900 12901 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 12902 try { 12903 final XmlSerializer serializer = new FastXmlSerializer(); 12904 serializer.setOutput(dataStream, "utf-8"); 12905 serializer.startDocument(null, true); 12906 serializer.startTag(null, TAG_PREFERRED_BACKUP); 12907 12908 synchronized (mPackages) { 12909 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 12910 } 12911 12912 serializer.endTag(null, TAG_PREFERRED_BACKUP); 12913 serializer.endDocument(); 12914 serializer.flush(); 12915 } catch (Exception e) { 12916 if (DEBUG_BACKUP) { 12917 Slog.e(TAG, "Unable to write preferred activities for backup", e); 12918 } 12919 return null; 12920 } 12921 12922 return dataStream.toByteArray(); 12923 } 12924 12925 @Override 12926 public void restorePreferredActivities(byte[] backup, int userId) { 12927 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12928 throw new SecurityException("Only the system may call restorePreferredActivities()"); 12929 } 12930 12931 try { 12932 final XmlPullParser parser = Xml.newPullParser(); 12933 parser.setInput(new ByteArrayInputStream(backup), null); 12934 12935 int type; 12936 while ((type = parser.next()) != XmlPullParser.START_TAG 12937 && type != XmlPullParser.END_DOCUMENT) { 12938 } 12939 if (type != XmlPullParser.START_TAG) { 12940 // oops didn't find a start tag?! 12941 if (DEBUG_BACKUP) { 12942 Slog.e(TAG, "Didn't find start tag during restore"); 12943 } 12944 return; 12945 } 12946 12947 // this is supposed to be TAG_PREFERRED_BACKUP 12948 if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) { 12949 if (DEBUG_BACKUP) { 12950 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 12951 } 12952 return; 12953 } 12954 12955 // skip interfering stuff, then we're aligned with the backing implementation 12956 while ((type = parser.next()) == XmlPullParser.TEXT) { } 12957 synchronized (mPackages) { 12958 mSettings.readPreferredActivitiesLPw(parser, userId); 12959 } 12960 } catch (Exception e) { 12961 if (DEBUG_BACKUP) { 12962 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 12963 } 12964 } 12965 } 12966 12967 @Override 12968 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 12969 int sourceUserId, int targetUserId, int flags) { 12970 mContext.enforceCallingOrSelfPermission( 12971 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 12972 int callingUid = Binder.getCallingUid(); 12973 enforceOwnerRights(ownerPackage, callingUid); 12974 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 12975 if (intentFilter.countActions() == 0) { 12976 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 12977 return; 12978 } 12979 synchronized (mPackages) { 12980 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 12981 ownerPackage, targetUserId, flags); 12982 CrossProfileIntentResolver resolver = 12983 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 12984 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 12985 // We have all those whose filter is equal. Now checking if the rest is equal as well. 12986 if (existing != null) { 12987 int size = existing.size(); 12988 for (int i = 0; i < size; i++) { 12989 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 12990 return; 12991 } 12992 } 12993 } 12994 resolver.addFilter(newFilter); 12995 scheduleWritePackageRestrictionsLocked(sourceUserId); 12996 } 12997 } 12998 12999 @Override 13000 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 13001 mContext.enforceCallingOrSelfPermission( 13002 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 13003 int callingUid = Binder.getCallingUid(); 13004 enforceOwnerRights(ownerPackage, callingUid); 13005 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 13006 synchronized (mPackages) { 13007 CrossProfileIntentResolver resolver = 13008 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 13009 ArraySet<CrossProfileIntentFilter> set = 13010 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 13011 for (CrossProfileIntentFilter filter : set) { 13012 if (filter.getOwnerPackage().equals(ownerPackage)) { 13013 resolver.removeFilter(filter); 13014 } 13015 } 13016 scheduleWritePackageRestrictionsLocked(sourceUserId); 13017 } 13018 } 13019 13020 // Enforcing that callingUid is owning pkg on userId 13021 private void enforceOwnerRights(String pkg, int callingUid) { 13022 // The system owns everything. 13023 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 13024 return; 13025 } 13026 int callingUserId = UserHandle.getUserId(callingUid); 13027 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 13028 if (pi == null) { 13029 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 13030 + callingUserId); 13031 } 13032 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 13033 throw new SecurityException("Calling uid " + callingUid 13034 + " does not own package " + pkg); 13035 } 13036 } 13037 13038 @Override 13039 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 13040 Intent intent = new Intent(Intent.ACTION_MAIN); 13041 intent.addCategory(Intent.CATEGORY_HOME); 13042 13043 final int callingUserId = UserHandle.getCallingUserId(); 13044 List<ResolveInfo> list = queryIntentActivities(intent, null, 13045 PackageManager.GET_META_DATA, callingUserId); 13046 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 13047 true, false, false, callingUserId); 13048 13049 allHomeCandidates.clear(); 13050 if (list != null) { 13051 for (ResolveInfo ri : list) { 13052 allHomeCandidates.add(ri); 13053 } 13054 } 13055 return (preferred == null || preferred.activityInfo == null) 13056 ? null 13057 : new ComponentName(preferred.activityInfo.packageName, 13058 preferred.activityInfo.name); 13059 } 13060 13061 @Override 13062 public void setApplicationEnabledSetting(String appPackageName, 13063 int newState, int flags, int userId, String callingPackage) { 13064 if (!sUserManager.exists(userId)) return; 13065 if (callingPackage == null) { 13066 callingPackage = Integer.toString(Binder.getCallingUid()); 13067 } 13068 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 13069 } 13070 13071 @Override 13072 public void setComponentEnabledSetting(ComponentName componentName, 13073 int newState, int flags, int userId) { 13074 if (!sUserManager.exists(userId)) return; 13075 setEnabledSetting(componentName.getPackageName(), 13076 componentName.getClassName(), newState, flags, userId, null); 13077 } 13078 13079 private void setEnabledSetting(final String packageName, String className, int newState, 13080 final int flags, int userId, String callingPackage) { 13081 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 13082 || newState == COMPONENT_ENABLED_STATE_ENABLED 13083 || newState == COMPONENT_ENABLED_STATE_DISABLED 13084 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 13085 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 13086 throw new IllegalArgumentException("Invalid new component state: " 13087 + newState); 13088 } 13089 PackageSetting pkgSetting; 13090 final int uid = Binder.getCallingUid(); 13091 final int permission = mContext.checkCallingOrSelfPermission( 13092 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 13093 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 13094 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 13095 boolean sendNow = false; 13096 boolean isApp = (className == null); 13097 String componentName = isApp ? packageName : className; 13098 int packageUid = -1; 13099 ArrayList<String> components; 13100 13101 // writer 13102 synchronized (mPackages) { 13103 pkgSetting = mSettings.mPackages.get(packageName); 13104 if (pkgSetting == null) { 13105 if (className == null) { 13106 throw new IllegalArgumentException( 13107 "Unknown package: " + packageName); 13108 } 13109 throw new IllegalArgumentException( 13110 "Unknown component: " + packageName 13111 + "/" + className); 13112 } 13113 // Allow root and verify that userId is not being specified by a different user 13114 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 13115 throw new SecurityException( 13116 "Permission Denial: attempt to change component state from pid=" 13117 + Binder.getCallingPid() 13118 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 13119 } 13120 if (className == null) { 13121 // We're dealing with an application/package level state change 13122 if (pkgSetting.getEnabled(userId) == newState) { 13123 // Nothing to do 13124 return; 13125 } 13126 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 13127 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 13128 // Don't care about who enables an app. 13129 callingPackage = null; 13130 } 13131 pkgSetting.setEnabled(newState, userId, callingPackage); 13132 // pkgSetting.pkg.mSetEnabled = newState; 13133 } else { 13134 // We're dealing with a component level state change 13135 // First, verify that this is a valid class name. 13136 PackageParser.Package pkg = pkgSetting.pkg; 13137 if (pkg == null || !pkg.hasComponentClassName(className)) { 13138 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 13139 throw new IllegalArgumentException("Component class " + className 13140 + " does not exist in " + packageName); 13141 } else { 13142 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 13143 + className + " does not exist in " + packageName); 13144 } 13145 } 13146 switch (newState) { 13147 case COMPONENT_ENABLED_STATE_ENABLED: 13148 if (!pkgSetting.enableComponentLPw(className, userId)) { 13149 return; 13150 } 13151 break; 13152 case COMPONENT_ENABLED_STATE_DISABLED: 13153 if (!pkgSetting.disableComponentLPw(className, userId)) { 13154 return; 13155 } 13156 break; 13157 case COMPONENT_ENABLED_STATE_DEFAULT: 13158 if (!pkgSetting.restoreComponentLPw(className, userId)) { 13159 return; 13160 } 13161 break; 13162 default: 13163 Slog.e(TAG, "Invalid new component state: " + newState); 13164 return; 13165 } 13166 } 13167 scheduleWritePackageRestrictionsLocked(userId); 13168 components = mPendingBroadcasts.get(userId, packageName); 13169 final boolean newPackage = components == null; 13170 if (newPackage) { 13171 components = new ArrayList<String>(); 13172 } 13173 if (!components.contains(componentName)) { 13174 components.add(componentName); 13175 } 13176 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 13177 sendNow = true; 13178 // Purge entry from pending broadcast list if another one exists already 13179 // since we are sending one right away. 13180 mPendingBroadcasts.remove(userId, packageName); 13181 } else { 13182 if (newPackage) { 13183 mPendingBroadcasts.put(userId, packageName, components); 13184 } 13185 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 13186 // Schedule a message 13187 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 13188 } 13189 } 13190 } 13191 13192 long callingId = Binder.clearCallingIdentity(); 13193 try { 13194 if (sendNow) { 13195 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 13196 sendPackageChangedBroadcast(packageName, 13197 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 13198 } 13199 } finally { 13200 Binder.restoreCallingIdentity(callingId); 13201 } 13202 } 13203 13204 private void sendPackageChangedBroadcast(String packageName, 13205 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 13206 if (DEBUG_INSTALL) 13207 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 13208 + componentNames); 13209 Bundle extras = new Bundle(4); 13210 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 13211 String nameList[] = new String[componentNames.size()]; 13212 componentNames.toArray(nameList); 13213 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 13214 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 13215 extras.putInt(Intent.EXTRA_UID, packageUid); 13216 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 13217 new int[] {UserHandle.getUserId(packageUid)}); 13218 } 13219 13220 @Override 13221 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 13222 if (!sUserManager.exists(userId)) return; 13223 final int uid = Binder.getCallingUid(); 13224 final int permission = mContext.checkCallingOrSelfPermission( 13225 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 13226 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 13227 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 13228 // writer 13229 synchronized (mPackages) { 13230 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 13231 allowedByPermission, uid, userId)) { 13232 scheduleWritePackageRestrictionsLocked(userId); 13233 } 13234 } 13235 } 13236 13237 @Override 13238 public String getInstallerPackageName(String packageName) { 13239 // reader 13240 synchronized (mPackages) { 13241 return mSettings.getInstallerPackageNameLPr(packageName); 13242 } 13243 } 13244 13245 @Override 13246 public int getApplicationEnabledSetting(String packageName, int userId) { 13247 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13248 int uid = Binder.getCallingUid(); 13249 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 13250 // reader 13251 synchronized (mPackages) { 13252 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 13253 } 13254 } 13255 13256 @Override 13257 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 13258 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13259 int uid = Binder.getCallingUid(); 13260 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 13261 // reader 13262 synchronized (mPackages) { 13263 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 13264 } 13265 } 13266 13267 @Override 13268 public void enterSafeMode() { 13269 enforceSystemOrRoot("Only the system can request entering safe mode"); 13270 13271 if (!mSystemReady) { 13272 mSafeMode = true; 13273 } 13274 } 13275 13276 @Override 13277 public void systemReady() { 13278 mSystemReady = true; 13279 13280 // Read the compatibilty setting when the system is ready. 13281 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 13282 mContext.getContentResolver(), 13283 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 13284 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 13285 if (DEBUG_SETTINGS) { 13286 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 13287 } 13288 13289 synchronized (mPackages) { 13290 // Verify that all of the preferred activity components actually 13291 // exist. It is possible for applications to be updated and at 13292 // that point remove a previously declared activity component that 13293 // had been set as a preferred activity. We try to clean this up 13294 // the next time we encounter that preferred activity, but it is 13295 // possible for the user flow to never be able to return to that 13296 // situation so here we do a sanity check to make sure we haven't 13297 // left any junk around. 13298 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 13299 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13300 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13301 removed.clear(); 13302 for (PreferredActivity pa : pir.filterSet()) { 13303 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 13304 removed.add(pa); 13305 } 13306 } 13307 if (removed.size() > 0) { 13308 for (int r=0; r<removed.size(); r++) { 13309 PreferredActivity pa = removed.get(r); 13310 Slog.w(TAG, "Removing dangling preferred activity: " 13311 + pa.mPref.mComponent); 13312 pir.removeFilter(pa); 13313 } 13314 mSettings.writePackageRestrictionsLPr( 13315 mSettings.mPreferredActivities.keyAt(i)); 13316 } 13317 } 13318 } 13319 sUserManager.systemReady(); 13320 13321 // Kick off any messages waiting for system ready 13322 if (mPostSystemReadyMessages != null) { 13323 for (Message msg : mPostSystemReadyMessages) { 13324 msg.sendToTarget(); 13325 } 13326 mPostSystemReadyMessages = null; 13327 } 13328 13329 // Watch for external volumes that come and go over time 13330 final StorageManager storage = mContext.getSystemService(StorageManager.class); 13331 storage.registerListener(mStorageListener); 13332 13333 mInstallerService.systemReady(); 13334 } 13335 13336 @Override 13337 public boolean isSafeMode() { 13338 return mSafeMode; 13339 } 13340 13341 @Override 13342 public boolean hasSystemUidErrors() { 13343 return mHasSystemUidErrors; 13344 } 13345 13346 static String arrayToString(int[] array) { 13347 StringBuffer buf = new StringBuffer(128); 13348 buf.append('['); 13349 if (array != null) { 13350 for (int i=0; i<array.length; i++) { 13351 if (i > 0) buf.append(", "); 13352 buf.append(array[i]); 13353 } 13354 } 13355 buf.append(']'); 13356 return buf.toString(); 13357 } 13358 13359 static class DumpState { 13360 public static final int DUMP_LIBS = 1 << 0; 13361 public static final int DUMP_FEATURES = 1 << 1; 13362 public static final int DUMP_RESOLVERS = 1 << 2; 13363 public static final int DUMP_PERMISSIONS = 1 << 3; 13364 public static final int DUMP_PACKAGES = 1 << 4; 13365 public static final int DUMP_SHARED_USERS = 1 << 5; 13366 public static final int DUMP_MESSAGES = 1 << 6; 13367 public static final int DUMP_PROVIDERS = 1 << 7; 13368 public static final int DUMP_VERIFIERS = 1 << 8; 13369 public static final int DUMP_PREFERRED = 1 << 9; 13370 public static final int DUMP_PREFERRED_XML = 1 << 10; 13371 public static final int DUMP_KEYSETS = 1 << 11; 13372 public static final int DUMP_VERSION = 1 << 12; 13373 public static final int DUMP_INSTALLS = 1 << 13; 13374 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14; 13375 public static final int DUMP_DOMAIN_PREFERRED = 1 << 15; 13376 13377 public static final int OPTION_SHOW_FILTERS = 1 << 0; 13378 13379 private int mTypes; 13380 13381 private int mOptions; 13382 13383 private boolean mTitlePrinted; 13384 13385 private SharedUserSetting mSharedUser; 13386 13387 public boolean isDumping(int type) { 13388 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 13389 return true; 13390 } 13391 13392 return (mTypes & type) != 0; 13393 } 13394 13395 public void setDump(int type) { 13396 mTypes |= type; 13397 } 13398 13399 public boolean isOptionEnabled(int option) { 13400 return (mOptions & option) != 0; 13401 } 13402 13403 public void setOptionEnabled(int option) { 13404 mOptions |= option; 13405 } 13406 13407 public boolean onTitlePrinted() { 13408 final boolean printed = mTitlePrinted; 13409 mTitlePrinted = true; 13410 return printed; 13411 } 13412 13413 public boolean getTitlePrinted() { 13414 return mTitlePrinted; 13415 } 13416 13417 public void setTitlePrinted(boolean enabled) { 13418 mTitlePrinted = enabled; 13419 } 13420 13421 public SharedUserSetting getSharedUser() { 13422 return mSharedUser; 13423 } 13424 13425 public void setSharedUser(SharedUserSetting user) { 13426 mSharedUser = user; 13427 } 13428 } 13429 13430 @Override 13431 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 13432 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 13433 != PackageManager.PERMISSION_GRANTED) { 13434 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 13435 + Binder.getCallingPid() 13436 + ", uid=" + Binder.getCallingUid() 13437 + " without permission " 13438 + android.Manifest.permission.DUMP); 13439 return; 13440 } 13441 13442 DumpState dumpState = new DumpState(); 13443 boolean fullPreferred = false; 13444 boolean checkin = false; 13445 13446 String packageName = null; 13447 13448 int opti = 0; 13449 while (opti < args.length) { 13450 String opt = args[opti]; 13451 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13452 break; 13453 } 13454 opti++; 13455 13456 if ("-a".equals(opt)) { 13457 // Right now we only know how to print all. 13458 } else if ("-h".equals(opt)) { 13459 pw.println("Package manager dump options:"); 13460 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 13461 pw.println(" --checkin: dump for a checkin"); 13462 pw.println(" -f: print details of intent filters"); 13463 pw.println(" -h: print this help"); 13464 pw.println(" cmd may be one of:"); 13465 pw.println(" l[ibraries]: list known shared libraries"); 13466 pw.println(" f[ibraries]: list device features"); 13467 pw.println(" k[eysets]: print known keysets"); 13468 pw.println(" r[esolvers]: dump intent resolvers"); 13469 pw.println(" perm[issions]: dump permissions"); 13470 pw.println(" pref[erred]: print preferred package settings"); 13471 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 13472 pw.println(" prov[iders]: dump content providers"); 13473 pw.println(" p[ackages]: dump installed packages"); 13474 pw.println(" s[hared-users]: dump shared user IDs"); 13475 pw.println(" m[essages]: print collected runtime messages"); 13476 pw.println(" v[erifiers]: print package verifier info"); 13477 pw.println(" version: print database version info"); 13478 pw.println(" write: write current settings now"); 13479 pw.println(" <package.name>: info about given package"); 13480 pw.println(" installs: details about install sessions"); 13481 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 13482 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 13483 return; 13484 } else if ("--checkin".equals(opt)) { 13485 checkin = true; 13486 } else if ("-f".equals(opt)) { 13487 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13488 } else { 13489 pw.println("Unknown argument: " + opt + "; use -h for help"); 13490 } 13491 } 13492 13493 // Is the caller requesting to dump a particular piece of data? 13494 if (opti < args.length) { 13495 String cmd = args[opti]; 13496 opti++; 13497 // Is this a package name? 13498 if ("android".equals(cmd) || cmd.contains(".")) { 13499 packageName = cmd; 13500 // When dumping a single package, we always dump all of its 13501 // filter information since the amount of data will be reasonable. 13502 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13503 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 13504 dumpState.setDump(DumpState.DUMP_LIBS); 13505 } else if ("f".equals(cmd) || "features".equals(cmd)) { 13506 dumpState.setDump(DumpState.DUMP_FEATURES); 13507 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 13508 dumpState.setDump(DumpState.DUMP_RESOLVERS); 13509 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 13510 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 13511 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 13512 dumpState.setDump(DumpState.DUMP_PREFERRED); 13513 } else if ("preferred-xml".equals(cmd)) { 13514 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 13515 if (opti < args.length && "--full".equals(args[opti])) { 13516 fullPreferred = true; 13517 opti++; 13518 } 13519 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 13520 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 13521 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 13522 dumpState.setDump(DumpState.DUMP_PACKAGES); 13523 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 13524 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 13525 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 13526 dumpState.setDump(DumpState.DUMP_PROVIDERS); 13527 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 13528 dumpState.setDump(DumpState.DUMP_MESSAGES); 13529 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 13530 dumpState.setDump(DumpState.DUMP_VERIFIERS); 13531 } else if ("i".equals(cmd) || "ifv".equals(cmd) 13532 || "intent-filter-verifiers".equals(cmd)) { 13533 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 13534 } else if ("version".equals(cmd)) { 13535 dumpState.setDump(DumpState.DUMP_VERSION); 13536 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 13537 dumpState.setDump(DumpState.DUMP_KEYSETS); 13538 } else if ("installs".equals(cmd)) { 13539 dumpState.setDump(DumpState.DUMP_INSTALLS); 13540 } else if ("write".equals(cmd)) { 13541 synchronized (mPackages) { 13542 mSettings.writeLPr(); 13543 pw.println("Settings written."); 13544 return; 13545 } 13546 } 13547 } 13548 13549 if (checkin) { 13550 pw.println("vers,1"); 13551 } 13552 13553 // reader 13554 synchronized (mPackages) { 13555 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 13556 if (!checkin) { 13557 if (dumpState.onTitlePrinted()) 13558 pw.println(); 13559 pw.println("Database versions:"); 13560 pw.print(" SDK Version:"); 13561 pw.print(" internal="); 13562 pw.print(mSettings.mInternalSdkPlatform); 13563 pw.print(" external="); 13564 pw.println(mSettings.mExternalSdkPlatform); 13565 pw.print(" DB Version:"); 13566 pw.print(" internal="); 13567 pw.print(mSettings.mInternalDatabaseVersion); 13568 pw.print(" external="); 13569 pw.println(mSettings.mExternalDatabaseVersion); 13570 } 13571 } 13572 13573 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 13574 if (!checkin) { 13575 if (dumpState.onTitlePrinted()) 13576 pw.println(); 13577 pw.println("Verifiers:"); 13578 pw.print(" Required: "); 13579 pw.print(mRequiredVerifierPackage); 13580 pw.print(" (uid="); 13581 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 13582 pw.println(")"); 13583 } else if (mRequiredVerifierPackage != null) { 13584 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 13585 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 13586 } 13587 } 13588 13589 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 13590 packageName == null) { 13591 if (mIntentFilterVerifierComponent != null) { 13592 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 13593 if (!checkin) { 13594 if (dumpState.onTitlePrinted()) 13595 pw.println(); 13596 pw.println("Intent Filter Verifier:"); 13597 pw.print(" Using: "); 13598 pw.print(verifierPackageName); 13599 pw.print(" (uid="); 13600 pw.print(getPackageUid(verifierPackageName, 0)); 13601 pw.println(")"); 13602 } else if (verifierPackageName != null) { 13603 pw.print("ifv,"); pw.print(verifierPackageName); 13604 pw.print(","); pw.println(getPackageUid(verifierPackageName, 0)); 13605 } 13606 } else { 13607 pw.println(); 13608 pw.println("No Intent Filter Verifier available!"); 13609 } 13610 } 13611 13612 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 13613 boolean printedHeader = false; 13614 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 13615 while (it.hasNext()) { 13616 String name = it.next(); 13617 SharedLibraryEntry ent = mSharedLibraries.get(name); 13618 if (!checkin) { 13619 if (!printedHeader) { 13620 if (dumpState.onTitlePrinted()) 13621 pw.println(); 13622 pw.println("Libraries:"); 13623 printedHeader = true; 13624 } 13625 pw.print(" "); 13626 } else { 13627 pw.print("lib,"); 13628 } 13629 pw.print(name); 13630 if (!checkin) { 13631 pw.print(" -> "); 13632 } 13633 if (ent.path != null) { 13634 if (!checkin) { 13635 pw.print("(jar) "); 13636 pw.print(ent.path); 13637 } else { 13638 pw.print(",jar,"); 13639 pw.print(ent.path); 13640 } 13641 } else { 13642 if (!checkin) { 13643 pw.print("(apk) "); 13644 pw.print(ent.apk); 13645 } else { 13646 pw.print(",apk,"); 13647 pw.print(ent.apk); 13648 } 13649 } 13650 pw.println(); 13651 } 13652 } 13653 13654 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 13655 if (dumpState.onTitlePrinted()) 13656 pw.println(); 13657 if (!checkin) { 13658 pw.println("Features:"); 13659 } 13660 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 13661 while (it.hasNext()) { 13662 String name = it.next(); 13663 if (!checkin) { 13664 pw.print(" "); 13665 } else { 13666 pw.print("feat,"); 13667 } 13668 pw.println(name); 13669 } 13670 } 13671 13672 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 13673 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 13674 : "Activity Resolver Table:", " ", packageName, 13675 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13676 dumpState.setTitlePrinted(true); 13677 } 13678 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 13679 : "Receiver Resolver Table:", " ", packageName, 13680 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13681 dumpState.setTitlePrinted(true); 13682 } 13683 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 13684 : "Service Resolver Table:", " ", packageName, 13685 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13686 dumpState.setTitlePrinted(true); 13687 } 13688 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 13689 : "Provider Resolver Table:", " ", packageName, 13690 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 13691 dumpState.setTitlePrinted(true); 13692 } 13693 } 13694 13695 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 13696 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13697 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13698 int user = mSettings.mPreferredActivities.keyAt(i); 13699 if (pir.dump(pw, 13700 dumpState.getTitlePrinted() 13701 ? "\nPreferred Activities User " + user + ":" 13702 : "Preferred Activities User " + user + ":", " ", 13703 packageName, true, false)) { 13704 dumpState.setTitlePrinted(true); 13705 } 13706 } 13707 } 13708 13709 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 13710 pw.flush(); 13711 FileOutputStream fout = new FileOutputStream(fd); 13712 BufferedOutputStream str = new BufferedOutputStream(fout); 13713 XmlSerializer serializer = new FastXmlSerializer(); 13714 try { 13715 serializer.setOutput(str, "utf-8"); 13716 serializer.startDocument(null, true); 13717 serializer.setFeature( 13718 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 13719 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 13720 serializer.endDocument(); 13721 serializer.flush(); 13722 } catch (IllegalArgumentException e) { 13723 pw.println("Failed writing: " + e); 13724 } catch (IllegalStateException e) { 13725 pw.println("Failed writing: " + e); 13726 } catch (IOException e) { 13727 pw.println("Failed writing: " + e); 13728 } 13729 } 13730 13731 if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) { 13732 pw.println(); 13733 int count = mSettings.mPackages.size(); 13734 if (count == 0) { 13735 pw.println("No domain preferred apps!"); 13736 pw.println(); 13737 } else { 13738 final String prefix = " "; 13739 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 13740 if (allPackageSettings.size() == 0) { 13741 pw.println("No domain preferred apps!"); 13742 pw.println(); 13743 } else { 13744 pw.println("Domain preferred apps status:"); 13745 pw.println(); 13746 count = 0; 13747 for (PackageSetting ps : allPackageSettings) { 13748 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 13749 if (ivi == null || ivi.getPackageName() == null) continue; 13750 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 13751 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 13752 pw.println(prefix + "Status: " + ivi.getStatusString()); 13753 pw.println(); 13754 count++; 13755 } 13756 if (count == 0) { 13757 pw.println(prefix + "No domain preferred app status!"); 13758 pw.println(); 13759 } 13760 for (int userId : sUserManager.getUserIds()) { 13761 pw.println("Domain preferred apps for User " + userId + ":"); 13762 pw.println(); 13763 count = 0; 13764 for (PackageSetting ps : allPackageSettings) { 13765 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 13766 if (ivi == null || ivi.getPackageName() == null) { 13767 continue; 13768 } 13769 final int status = ps.getDomainVerificationStatusForUser(userId); 13770 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 13771 continue; 13772 } 13773 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 13774 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 13775 String statusStr = IntentFilterVerificationInfo. 13776 getStatusStringFromValue(status); 13777 pw.println(prefix + "Status: " + statusStr); 13778 pw.println(); 13779 count++; 13780 } 13781 if (count == 0) { 13782 pw.println(prefix + "No domain preferred apps!"); 13783 pw.println(); 13784 } 13785 } 13786 } 13787 } 13788 } 13789 13790 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 13791 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 13792 if (packageName == null) { 13793 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 13794 if (iperm == 0) { 13795 if (dumpState.onTitlePrinted()) 13796 pw.println(); 13797 pw.println("AppOp Permissions:"); 13798 } 13799 pw.print(" AppOp Permission "); 13800 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 13801 pw.println(":"); 13802 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 13803 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 13804 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 13805 } 13806 } 13807 } 13808 } 13809 13810 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 13811 boolean printedSomething = false; 13812 for (PackageParser.Provider p : mProviders.mProviders.values()) { 13813 if (packageName != null && !packageName.equals(p.info.packageName)) { 13814 continue; 13815 } 13816 if (!printedSomething) { 13817 if (dumpState.onTitlePrinted()) 13818 pw.println(); 13819 pw.println("Registered ContentProviders:"); 13820 printedSomething = true; 13821 } 13822 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 13823 pw.print(" "); pw.println(p.toString()); 13824 } 13825 printedSomething = false; 13826 for (Map.Entry<String, PackageParser.Provider> entry : 13827 mProvidersByAuthority.entrySet()) { 13828 PackageParser.Provider p = entry.getValue(); 13829 if (packageName != null && !packageName.equals(p.info.packageName)) { 13830 continue; 13831 } 13832 if (!printedSomething) { 13833 if (dumpState.onTitlePrinted()) 13834 pw.println(); 13835 pw.println("ContentProvider Authorities:"); 13836 printedSomething = true; 13837 } 13838 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 13839 pw.print(" "); pw.println(p.toString()); 13840 if (p.info != null && p.info.applicationInfo != null) { 13841 final String appInfo = p.info.applicationInfo.toString(); 13842 pw.print(" applicationInfo="); pw.println(appInfo); 13843 } 13844 } 13845 } 13846 13847 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 13848 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 13849 } 13850 13851 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 13852 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 13853 } 13854 13855 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 13856 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin); 13857 } 13858 13859 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 13860 // XXX should handle packageName != null by dumping only install data that 13861 // the given package is involved with. 13862 if (dumpState.onTitlePrinted()) pw.println(); 13863 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 13864 } 13865 13866 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 13867 if (dumpState.onTitlePrinted()) pw.println(); 13868 mSettings.dumpReadMessagesLPr(pw, dumpState); 13869 13870 pw.println(); 13871 pw.println("Package warning messages:"); 13872 BufferedReader in = null; 13873 String line = null; 13874 try { 13875 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 13876 while ((line = in.readLine()) != null) { 13877 if (line.contains("ignored: updated version")) continue; 13878 pw.println(line); 13879 } 13880 } catch (IOException ignored) { 13881 } finally { 13882 IoUtils.closeQuietly(in); 13883 } 13884 } 13885 13886 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 13887 BufferedReader in = null; 13888 String line = null; 13889 try { 13890 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 13891 while ((line = in.readLine()) != null) { 13892 if (line.contains("ignored: updated version")) continue; 13893 pw.print("msg,"); 13894 pw.println(line); 13895 } 13896 } catch (IOException ignored) { 13897 } finally { 13898 IoUtils.closeQuietly(in); 13899 } 13900 } 13901 } 13902 } 13903 13904 // ------- apps on sdcard specific code ------- 13905 static final boolean DEBUG_SD_INSTALL = false; 13906 13907 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 13908 13909 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 13910 13911 private boolean mMediaMounted = false; 13912 13913 static String getEncryptKey() { 13914 try { 13915 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 13916 SD_ENCRYPTION_KEYSTORE_NAME); 13917 if (sdEncKey == null) { 13918 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 13919 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 13920 if (sdEncKey == null) { 13921 Slog.e(TAG, "Failed to create encryption keys"); 13922 return null; 13923 } 13924 } 13925 return sdEncKey; 13926 } catch (NoSuchAlgorithmException nsae) { 13927 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 13928 return null; 13929 } catch (IOException ioe) { 13930 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 13931 return null; 13932 } 13933 } 13934 13935 /* 13936 * Update media status on PackageManager. 13937 */ 13938 @Override 13939 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 13940 int callingUid = Binder.getCallingUid(); 13941 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13942 throw new SecurityException("Media status can only be updated by the system"); 13943 } 13944 // reader; this apparently protects mMediaMounted, but should probably 13945 // be a different lock in that case. 13946 synchronized (mPackages) { 13947 Log.i(TAG, "Updating external media status from " 13948 + (mMediaMounted ? "mounted" : "unmounted") + " to " 13949 + (mediaStatus ? "mounted" : "unmounted")); 13950 if (DEBUG_SD_INSTALL) 13951 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 13952 + ", mMediaMounted=" + mMediaMounted); 13953 if (mediaStatus == mMediaMounted) { 13954 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 13955 : 0, -1); 13956 mHandler.sendMessage(msg); 13957 return; 13958 } 13959 mMediaMounted = mediaStatus; 13960 } 13961 // Queue up an async operation since the package installation may take a 13962 // little while. 13963 mHandler.post(new Runnable() { 13964 public void run() { 13965 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 13966 } 13967 }); 13968 } 13969 13970 /** 13971 * Called by MountService when the initial ASECs to scan are available. 13972 * Should block until all the ASEC containers are finished being scanned. 13973 */ 13974 public void scanAvailableAsecs() { 13975 updateExternalMediaStatusInner(true, false, false); 13976 if (mShouldRestoreconData) { 13977 SELinuxMMAC.setRestoreconDone(); 13978 mShouldRestoreconData = false; 13979 } 13980 } 13981 13982 /* 13983 * Collect information of applications on external media, map them against 13984 * existing containers and update information based on current mount status. 13985 * Please note that we always have to report status if reportStatus has been 13986 * set to true especially when unloading packages. 13987 */ 13988 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 13989 boolean externalStorage) { 13990 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 13991 int[] uidArr = EmptyArray.INT; 13992 13993 final String[] list = PackageHelper.getSecureContainerList(); 13994 if (ArrayUtils.isEmpty(list)) { 13995 Log.i(TAG, "No secure containers found"); 13996 } else { 13997 // Process list of secure containers and categorize them 13998 // as active or stale based on their package internal state. 13999 14000 // reader 14001 synchronized (mPackages) { 14002 for (String cid : list) { 14003 // Leave stages untouched for now; installer service owns them 14004 if (PackageInstallerService.isStageName(cid)) continue; 14005 14006 if (DEBUG_SD_INSTALL) 14007 Log.i(TAG, "Processing container " + cid); 14008 String pkgName = getAsecPackageName(cid); 14009 if (pkgName == null) { 14010 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 14011 continue; 14012 } 14013 if (DEBUG_SD_INSTALL) 14014 Log.i(TAG, "Looking for pkg : " + pkgName); 14015 14016 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14017 if (ps == null) { 14018 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 14019 continue; 14020 } 14021 14022 /* 14023 * Skip packages that are not external if we're unmounting 14024 * external storage. 14025 */ 14026 if (externalStorage && !isMounted && !isExternal(ps)) { 14027 continue; 14028 } 14029 14030 final AsecInstallArgs args = new AsecInstallArgs(cid, 14031 getAppDexInstructionSets(ps), ps.isForwardLocked()); 14032 // The package status is changed only if the code path 14033 // matches between settings and the container id. 14034 if (ps.codePathString != null 14035 && ps.codePathString.startsWith(args.getCodePath())) { 14036 if (DEBUG_SD_INSTALL) { 14037 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 14038 + " at code path: " + ps.codePathString); 14039 } 14040 14041 // We do have a valid package installed on sdcard 14042 processCids.put(args, ps.codePathString); 14043 final int uid = ps.appId; 14044 if (uid != -1) { 14045 uidArr = ArrayUtils.appendInt(uidArr, uid); 14046 } 14047 } else { 14048 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 14049 + ps.codePathString); 14050 } 14051 } 14052 } 14053 14054 Arrays.sort(uidArr); 14055 } 14056 14057 // Process packages with valid entries. 14058 if (isMounted) { 14059 if (DEBUG_SD_INSTALL) 14060 Log.i(TAG, "Loading packages"); 14061 loadMediaPackages(processCids, uidArr); 14062 startCleaningPackages(); 14063 mInstallerService.onSecureContainersAvailable(); 14064 } else { 14065 if (DEBUG_SD_INSTALL) 14066 Log.i(TAG, "Unloading packages"); 14067 unloadMediaPackages(processCids, uidArr, reportStatus); 14068 } 14069 } 14070 14071 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 14072 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 14073 final int size = infos.size(); 14074 final String[] packageNames = new String[size]; 14075 final int[] packageUids = new int[size]; 14076 for (int i = 0; i < size; i++) { 14077 final ApplicationInfo info = infos.get(i); 14078 packageNames[i] = info.packageName; 14079 packageUids[i] = info.uid; 14080 } 14081 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 14082 finishedReceiver); 14083 } 14084 14085 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 14086 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 14087 sendResourcesChangedBroadcast(mediaStatus, replacing, 14088 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 14089 } 14090 14091 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 14092 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 14093 int size = pkgList.length; 14094 if (size > 0) { 14095 // Send broadcasts here 14096 Bundle extras = new Bundle(); 14097 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 14098 if (uidArr != null) { 14099 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 14100 } 14101 if (replacing) { 14102 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 14103 } 14104 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 14105 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 14106 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 14107 } 14108 } 14109 14110 /* 14111 * Look at potentially valid container ids from processCids If package 14112 * information doesn't match the one on record or package scanning fails, 14113 * the cid is added to list of removeCids. We currently don't delete stale 14114 * containers. 14115 */ 14116 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) { 14117 ArrayList<String> pkgList = new ArrayList<String>(); 14118 Set<AsecInstallArgs> keys = processCids.keySet(); 14119 14120 for (AsecInstallArgs args : keys) { 14121 String codePath = processCids.get(args); 14122 if (DEBUG_SD_INSTALL) 14123 Log.i(TAG, "Loading container : " + args.cid); 14124 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14125 try { 14126 // Make sure there are no container errors first. 14127 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 14128 Slog.e(TAG, "Failed to mount cid : " + args.cid 14129 + " when installing from sdcard"); 14130 continue; 14131 } 14132 // Check code path here. 14133 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 14134 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 14135 + " does not match one in settings " + codePath); 14136 continue; 14137 } 14138 // Parse package 14139 int parseFlags = mDefParseFlags; 14140 if (args.isExternalAsec()) { 14141 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 14142 } 14143 if (args.isFwdLocked()) { 14144 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 14145 } 14146 14147 synchronized (mInstallLock) { 14148 PackageParser.Package pkg = null; 14149 try { 14150 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null); 14151 } catch (PackageManagerException e) { 14152 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 14153 } 14154 // Scan the package 14155 if (pkg != null) { 14156 /* 14157 * TODO why is the lock being held? doPostInstall is 14158 * called in other places without the lock. This needs 14159 * to be straightened out. 14160 */ 14161 // writer 14162 synchronized (mPackages) { 14163 retCode = PackageManager.INSTALL_SUCCEEDED; 14164 pkgList.add(pkg.packageName); 14165 // Post process args 14166 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 14167 pkg.applicationInfo.uid); 14168 } 14169 } else { 14170 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 14171 } 14172 } 14173 14174 } finally { 14175 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 14176 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 14177 } 14178 } 14179 } 14180 // writer 14181 synchronized (mPackages) { 14182 // If the platform SDK has changed since the last time we booted, 14183 // we need to re-grant app permission to catch any new ones that 14184 // appear. This is really a hack, and means that apps can in some 14185 // cases get permissions that the user didn't initially explicitly 14186 // allow... it would be nice to have some better way to handle 14187 // this situation. 14188 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 14189 if (regrantPermissions) 14190 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 14191 + mSdkVersion + "; regranting permissions for external storage"); 14192 mSettings.mExternalSdkPlatform = mSdkVersion; 14193 14194 // Make sure group IDs have been assigned, and any permission 14195 // changes in other apps are accounted for 14196 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 14197 | (regrantPermissions 14198 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 14199 : 0)); 14200 14201 mSettings.updateExternalDatabaseVersion(); 14202 14203 // can downgrade to reader 14204 // Persist settings 14205 mSettings.writeLPr(); 14206 } 14207 // Send a broadcast to let everyone know we are done processing 14208 if (pkgList.size() > 0) { 14209 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 14210 } 14211 } 14212 14213 /* 14214 * Utility method to unload a list of specified containers 14215 */ 14216 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 14217 // Just unmount all valid containers. 14218 for (AsecInstallArgs arg : cidArgs) { 14219 synchronized (mInstallLock) { 14220 arg.doPostDeleteLI(false); 14221 } 14222 } 14223 } 14224 14225 /* 14226 * Unload packages mounted on external media. This involves deleting package 14227 * data from internal structures, sending broadcasts about diabled packages, 14228 * gc'ing to free up references, unmounting all secure containers 14229 * corresponding to packages on external media, and posting a 14230 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 14231 * that we always have to post this message if status has been requested no 14232 * matter what. 14233 */ 14234 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 14235 final boolean reportStatus) { 14236 if (DEBUG_SD_INSTALL) 14237 Log.i(TAG, "unloading media packages"); 14238 ArrayList<String> pkgList = new ArrayList<String>(); 14239 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 14240 final Set<AsecInstallArgs> keys = processCids.keySet(); 14241 for (AsecInstallArgs args : keys) { 14242 String pkgName = args.getPackageName(); 14243 if (DEBUG_SD_INSTALL) 14244 Log.i(TAG, "Trying to unload pkg : " + pkgName); 14245 // Delete package internally 14246 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14247 synchronized (mInstallLock) { 14248 boolean res = deletePackageLI(pkgName, null, false, null, null, 14249 PackageManager.DELETE_KEEP_DATA, outInfo, false); 14250 if (res) { 14251 pkgList.add(pkgName); 14252 } else { 14253 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 14254 failedList.add(args); 14255 } 14256 } 14257 } 14258 14259 // reader 14260 synchronized (mPackages) { 14261 // We didn't update the settings after removing each package; 14262 // write them now for all packages. 14263 mSettings.writeLPr(); 14264 } 14265 14266 // We have to absolutely send UPDATED_MEDIA_STATUS only 14267 // after confirming that all the receivers processed the ordered 14268 // broadcast when packages get disabled, force a gc to clean things up. 14269 // and unload all the containers. 14270 if (pkgList.size() > 0) { 14271 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 14272 new IIntentReceiver.Stub() { 14273 public void performReceive(Intent intent, int resultCode, String data, 14274 Bundle extras, boolean ordered, boolean sticky, 14275 int sendingUser) throws RemoteException { 14276 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 14277 reportStatus ? 1 : 0, 1, keys); 14278 mHandler.sendMessage(msg); 14279 } 14280 }); 14281 } else { 14282 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 14283 keys); 14284 mHandler.sendMessage(msg); 14285 } 14286 } 14287 14288 private void loadPrivatePackages(VolumeInfo vol) { 14289 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 14290 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 14291 synchronized (mInstallLock) { 14292 synchronized (mPackages) { 14293 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14294 for (PackageSetting ps : packages) { 14295 final PackageParser.Package pkg; 14296 try { 14297 pkg = scanPackageLI(ps.codePath, parseFlags, 0, 0, null); 14298 loaded.add(pkg.applicationInfo); 14299 } catch (PackageManagerException e) { 14300 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 14301 } 14302 } 14303 14304 // TODO: regrant any permissions that changed based since original install 14305 14306 mSettings.writeLPr(); 14307 } 14308 } 14309 14310 Slog.d(TAG, "Loaded packages " + loaded); 14311 sendResourcesChangedBroadcast(true, false, loaded, null); 14312 } 14313 14314 private void unloadPrivatePackages(VolumeInfo vol) { 14315 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 14316 synchronized (mInstallLock) { 14317 synchronized (mPackages) { 14318 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14319 for (PackageSetting ps : packages) { 14320 if (ps.pkg == null) continue; 14321 14322 final ApplicationInfo info = ps.pkg.applicationInfo; 14323 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14324 if (deletePackageLI(ps.name, null, false, null, null, 14325 PackageManager.DELETE_KEEP_DATA, outInfo, false)) { 14326 unloaded.add(info); 14327 } else { 14328 Slog.w(TAG, "Failed to unload " + ps.codePath); 14329 } 14330 } 14331 14332 mSettings.writeLPr(); 14333 } 14334 } 14335 14336 Slog.d(TAG, "Unloaded packages " + unloaded); 14337 sendResourcesChangedBroadcast(false, false, unloaded, null); 14338 } 14339 14340 private void unfreezePackage(String packageName) { 14341 synchronized (mPackages) { 14342 final PackageSetting ps = mSettings.mPackages.get(packageName); 14343 if (ps != null) { 14344 ps.frozen = false; 14345 } 14346 } 14347 } 14348 14349 @Override 14350 public int movePackage(final String packageName, final String volumeUuid) { 14351 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14352 14353 final int moveId = mNextMoveId.getAndIncrement(); 14354 try { 14355 movePackageInternal(packageName, volumeUuid, moveId); 14356 } catch (PackageManagerException e) { 14357 Slog.d(TAG, "Failed to move " + packageName, e); 14358 mMoveCallbacks.notifyStatusChanged(moveId, 14359 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 14360 } 14361 return moveId; 14362 } 14363 14364 private void movePackageInternal(final String packageName, final String volumeUuid, 14365 final int moveId) throws PackageManagerException { 14366 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 14367 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14368 final PackageManager pm = mContext.getPackageManager(); 14369 14370 final boolean currentAsec; 14371 final String currentVolumeUuid; 14372 final File codeFile; 14373 final String installerPackageName; 14374 final String packageAbiOverride; 14375 final int appId; 14376 final String seinfo; 14377 final String label; 14378 14379 // reader 14380 synchronized (mPackages) { 14381 final PackageParser.Package pkg = mPackages.get(packageName); 14382 final PackageSetting ps = mSettings.mPackages.get(packageName); 14383 if (pkg == null || ps == null) { 14384 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 14385 } 14386 14387 if (pkg.applicationInfo.isSystemApp()) { 14388 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 14389 "Cannot move system application"); 14390 } 14391 14392 if (Objects.equals(ps.volumeUuid, volumeUuid)) { 14393 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14394 "Package already moved to " + volumeUuid); 14395 } 14396 14397 final File probe = new File(pkg.codePath); 14398 final File probeOat = new File(probe, "oat"); 14399 if (!probe.isDirectory() || !probeOat.isDirectory()) { 14400 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14401 "Move only supported for modern cluster style installs"); 14402 } 14403 14404 if (ps.frozen) { 14405 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 14406 "Failed to move already frozen package"); 14407 } 14408 ps.frozen = true; 14409 14410 currentAsec = pkg.applicationInfo.isForwardLocked() 14411 || pkg.applicationInfo.isExternalAsec(); 14412 currentVolumeUuid = ps.volumeUuid; 14413 codeFile = new File(pkg.codePath); 14414 installerPackageName = ps.installerPackageName; 14415 packageAbiOverride = ps.cpuAbiOverrideString; 14416 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 14417 seinfo = pkg.applicationInfo.seinfo; 14418 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 14419 } 14420 14421 // Now that we're guarded by frozen state, kill app during move 14422 killApplication(packageName, appId, "move pkg"); 14423 14424 final Bundle extras = new Bundle(); 14425 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 14426 extras.putString(Intent.EXTRA_TITLE, label); 14427 mMoveCallbacks.notifyCreated(moveId, extras); 14428 14429 int installFlags; 14430 final boolean moveCompleteApp; 14431 final File measurePath; 14432 14433 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 14434 installFlags = INSTALL_INTERNAL; 14435 moveCompleteApp = !currentAsec; 14436 measurePath = Environment.getDataAppDirectory(volumeUuid); 14437 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 14438 installFlags = INSTALL_EXTERNAL; 14439 moveCompleteApp = false; 14440 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 14441 } else { 14442 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 14443 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 14444 || !volume.isMountedWritable()) { 14445 unfreezePackage(packageName); 14446 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14447 "Move location not mounted private volume"); 14448 } 14449 14450 Preconditions.checkState(!currentAsec); 14451 14452 installFlags = INSTALL_INTERNAL; 14453 moveCompleteApp = true; 14454 measurePath = Environment.getDataAppDirectory(volumeUuid); 14455 } 14456 14457 final PackageStats stats = new PackageStats(null, -1); 14458 synchronized (mInstaller) { 14459 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 14460 unfreezePackage(packageName); 14461 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14462 "Failed to measure package size"); 14463 } 14464 } 14465 14466 Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " + stats.dataSize); 14467 14468 final long startFreeBytes = measurePath.getFreeSpace(); 14469 final long sizeBytes; 14470 if (moveCompleteApp) { 14471 sizeBytes = stats.codeSize + stats.dataSize; 14472 } else { 14473 sizeBytes = stats.codeSize; 14474 } 14475 14476 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 14477 unfreezePackage(packageName); 14478 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14479 "Not enough free space to move"); 14480 } 14481 14482 mMoveCallbacks.notifyStatusChanged(moveId, 10); 14483 14484 final CountDownLatch installedLatch = new CountDownLatch(1); 14485 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 14486 @Override 14487 public void onUserActionRequired(Intent intent) throws RemoteException { 14488 throw new IllegalStateException(); 14489 } 14490 14491 @Override 14492 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 14493 Bundle extras) throws RemoteException { 14494 Slog.d(TAG, "Install result for move: " 14495 + PackageManager.installStatusToString(returnCode, msg)); 14496 14497 installedLatch.countDown(); 14498 14499 // Regardless of success or failure of the move operation, 14500 // always unfreeze the package 14501 unfreezePackage(packageName); 14502 14503 final int status = PackageManager.installStatusToPublicStatus(returnCode); 14504 switch (status) { 14505 case PackageInstaller.STATUS_SUCCESS: 14506 mMoveCallbacks.notifyStatusChanged(moveId, 14507 PackageManager.MOVE_SUCCEEDED); 14508 break; 14509 case PackageInstaller.STATUS_FAILURE_STORAGE: 14510 mMoveCallbacks.notifyStatusChanged(moveId, 14511 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 14512 break; 14513 default: 14514 mMoveCallbacks.notifyStatusChanged(moveId, 14515 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 14516 break; 14517 } 14518 } 14519 }; 14520 14521 final MoveInfo move; 14522 if (moveCompleteApp) { 14523 // Kick off a thread to report progress estimates 14524 new Thread() { 14525 @Override 14526 public void run() { 14527 while (true) { 14528 try { 14529 if (installedLatch.await(1, TimeUnit.SECONDS)) { 14530 break; 14531 } 14532 } catch (InterruptedException ignored) { 14533 } 14534 14535 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 14536 final int progress = 10 + (int) MathUtils.constrain( 14537 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 14538 mMoveCallbacks.notifyStatusChanged(moveId, progress); 14539 } 14540 } 14541 }.start(); 14542 14543 final String dataAppName = codeFile.getName(); 14544 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 14545 dataAppName, appId, seinfo); 14546 } else { 14547 move = null; 14548 } 14549 14550 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 14551 14552 final Message msg = mHandler.obtainMessage(INIT_COPY); 14553 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 14554 msg.obj = new InstallParams(origin, move, installObserver, installFlags, 14555 installerPackageName, volumeUuid, null, user, packageAbiOverride); 14556 mHandler.sendMessage(msg); 14557 } 14558 14559 @Override 14560 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 14561 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14562 14563 final int realMoveId = mNextMoveId.getAndIncrement(); 14564 final Bundle extras = new Bundle(); 14565 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 14566 mMoveCallbacks.notifyCreated(realMoveId, extras); 14567 14568 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 14569 @Override 14570 public void onCreated(int moveId, Bundle extras) { 14571 // Ignored 14572 } 14573 14574 @Override 14575 public void onStatusChanged(int moveId, int status, long estMillis) { 14576 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 14577 } 14578 }; 14579 14580 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14581 storage.setPrimaryStorageUuid(volumeUuid, callback); 14582 return realMoveId; 14583 } 14584 14585 @Override 14586 public int getMoveStatus(int moveId) { 14587 mContext.enforceCallingOrSelfPermission( 14588 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14589 return mMoveCallbacks.mLastStatus.get(moveId); 14590 } 14591 14592 @Override 14593 public void registerMoveCallback(IPackageMoveObserver callback) { 14594 mContext.enforceCallingOrSelfPermission( 14595 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14596 mMoveCallbacks.register(callback); 14597 } 14598 14599 @Override 14600 public void unregisterMoveCallback(IPackageMoveObserver callback) { 14601 mContext.enforceCallingOrSelfPermission( 14602 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14603 mMoveCallbacks.unregister(callback); 14604 } 14605 14606 @Override 14607 public boolean setInstallLocation(int loc) { 14608 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 14609 null); 14610 if (getInstallLocation() == loc) { 14611 return true; 14612 } 14613 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 14614 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 14615 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 14616 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 14617 return true; 14618 } 14619 return false; 14620 } 14621 14622 @Override 14623 public int getInstallLocation() { 14624 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 14625 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 14626 PackageHelper.APP_INSTALL_AUTO); 14627 } 14628 14629 /** Called by UserManagerService */ 14630 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 14631 mDirtyUsers.remove(userHandle); 14632 mSettings.removeUserLPw(userHandle); 14633 mPendingBroadcasts.remove(userHandle); 14634 if (mInstaller != null) { 14635 // Technically, we shouldn't be doing this with the package lock 14636 // held. However, this is very rare, and there is already so much 14637 // other disk I/O going on, that we'll let it slide for now. 14638 final StorageManager storage = StorageManager.from(mContext); 14639 final List<VolumeInfo> vols = storage.getVolumes(); 14640 for (VolumeInfo vol : vols) { 14641 if (vol.getType() == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) { 14642 final String volumeUuid = vol.getFsUuid(); 14643 Slog.d(TAG, "Removing user data on volume " + volumeUuid); 14644 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 14645 } 14646 } 14647 } 14648 mUserNeedsBadging.delete(userHandle); 14649 removeUnusedPackagesLILPw(userManager, userHandle); 14650 } 14651 14652 /** 14653 * We're removing userHandle and would like to remove any downloaded packages 14654 * that are no longer in use by any other user. 14655 * @param userHandle the user being removed 14656 */ 14657 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 14658 final boolean DEBUG_CLEAN_APKS = false; 14659 int [] users = userManager.getUserIdsLPr(); 14660 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 14661 while (psit.hasNext()) { 14662 PackageSetting ps = psit.next(); 14663 if (ps.pkg == null) { 14664 continue; 14665 } 14666 final String packageName = ps.pkg.packageName; 14667 // Skip over if system app 14668 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14669 continue; 14670 } 14671 if (DEBUG_CLEAN_APKS) { 14672 Slog.i(TAG, "Checking package " + packageName); 14673 } 14674 boolean keep = false; 14675 for (int i = 0; i < users.length; i++) { 14676 if (users[i] != userHandle && ps.getInstalled(users[i])) { 14677 keep = true; 14678 if (DEBUG_CLEAN_APKS) { 14679 Slog.i(TAG, " Keeping package " + packageName + " for user " 14680 + users[i]); 14681 } 14682 break; 14683 } 14684 } 14685 if (!keep) { 14686 if (DEBUG_CLEAN_APKS) { 14687 Slog.i(TAG, " Removing package " + packageName); 14688 } 14689 mHandler.post(new Runnable() { 14690 public void run() { 14691 deletePackageX(packageName, userHandle, 0); 14692 } //end run 14693 }); 14694 } 14695 } 14696 } 14697 14698 /** Called by UserManagerService */ 14699 void createNewUserLILPw(int userHandle, File path) { 14700 if (mInstaller != null) { 14701 mInstaller.createUserConfig(userHandle); 14702 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 14703 } 14704 } 14705 14706 void newUserCreatedLILPw(int userHandle) { 14707 // Adding a user requires updating runtime permissions for system apps. 14708 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 14709 } 14710 14711 @Override 14712 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 14713 mContext.enforceCallingOrSelfPermission( 14714 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 14715 "Only package verification agents can read the verifier device identity"); 14716 14717 synchronized (mPackages) { 14718 return mSettings.getVerifierDeviceIdentityLPw(); 14719 } 14720 } 14721 14722 @Override 14723 public void setPermissionEnforced(String permission, boolean enforced) { 14724 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 14725 if (READ_EXTERNAL_STORAGE.equals(permission)) { 14726 synchronized (mPackages) { 14727 if (mSettings.mReadExternalStorageEnforced == null 14728 || mSettings.mReadExternalStorageEnforced != enforced) { 14729 mSettings.mReadExternalStorageEnforced = enforced; 14730 mSettings.writeLPr(); 14731 } 14732 } 14733 // kill any non-foreground processes so we restart them and 14734 // grant/revoke the GID. 14735 final IActivityManager am = ActivityManagerNative.getDefault(); 14736 if (am != null) { 14737 final long token = Binder.clearCallingIdentity(); 14738 try { 14739 am.killProcessesBelowForeground("setPermissionEnforcement"); 14740 } catch (RemoteException e) { 14741 } finally { 14742 Binder.restoreCallingIdentity(token); 14743 } 14744 } 14745 } else { 14746 throw new IllegalArgumentException("No selective enforcement for " + permission); 14747 } 14748 } 14749 14750 @Override 14751 @Deprecated 14752 public boolean isPermissionEnforced(String permission) { 14753 return true; 14754 } 14755 14756 @Override 14757 public boolean isStorageLow() { 14758 final long token = Binder.clearCallingIdentity(); 14759 try { 14760 final DeviceStorageMonitorInternal 14761 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 14762 if (dsm != null) { 14763 return dsm.isMemoryLow(); 14764 } else { 14765 return false; 14766 } 14767 } finally { 14768 Binder.restoreCallingIdentity(token); 14769 } 14770 } 14771 14772 @Override 14773 public IPackageInstaller getPackageInstaller() { 14774 return mInstallerService; 14775 } 14776 14777 private boolean userNeedsBadging(int userId) { 14778 int index = mUserNeedsBadging.indexOfKey(userId); 14779 if (index < 0) { 14780 final UserInfo userInfo; 14781 final long token = Binder.clearCallingIdentity(); 14782 try { 14783 userInfo = sUserManager.getUserInfo(userId); 14784 } finally { 14785 Binder.restoreCallingIdentity(token); 14786 } 14787 final boolean b; 14788 if (userInfo != null && userInfo.isManagedProfile()) { 14789 b = true; 14790 } else { 14791 b = false; 14792 } 14793 mUserNeedsBadging.put(userId, b); 14794 return b; 14795 } 14796 return mUserNeedsBadging.valueAt(index); 14797 } 14798 14799 @Override 14800 public KeySet getKeySetByAlias(String packageName, String alias) { 14801 if (packageName == null || alias == null) { 14802 return null; 14803 } 14804 synchronized(mPackages) { 14805 final PackageParser.Package pkg = mPackages.get(packageName); 14806 if (pkg == null) { 14807 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14808 throw new IllegalArgumentException("Unknown package: " + packageName); 14809 } 14810 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14811 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 14812 } 14813 } 14814 14815 @Override 14816 public KeySet getSigningKeySet(String packageName) { 14817 if (packageName == null) { 14818 return null; 14819 } 14820 synchronized(mPackages) { 14821 final PackageParser.Package pkg = mPackages.get(packageName); 14822 if (pkg == null) { 14823 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14824 throw new IllegalArgumentException("Unknown package: " + packageName); 14825 } 14826 if (pkg.applicationInfo.uid != Binder.getCallingUid() 14827 && Process.SYSTEM_UID != Binder.getCallingUid()) { 14828 throw new SecurityException("May not access signing KeySet of other apps."); 14829 } 14830 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14831 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 14832 } 14833 } 14834 14835 @Override 14836 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 14837 if (packageName == null || ks == null) { 14838 return false; 14839 } 14840 synchronized(mPackages) { 14841 final PackageParser.Package pkg = mPackages.get(packageName); 14842 if (pkg == null) { 14843 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14844 throw new IllegalArgumentException("Unknown package: " + packageName); 14845 } 14846 IBinder ksh = ks.getToken(); 14847 if (ksh instanceof KeySetHandle) { 14848 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14849 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 14850 } 14851 return false; 14852 } 14853 } 14854 14855 @Override 14856 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 14857 if (packageName == null || ks == null) { 14858 return false; 14859 } 14860 synchronized(mPackages) { 14861 final PackageParser.Package pkg = mPackages.get(packageName); 14862 if (pkg == null) { 14863 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 14864 throw new IllegalArgumentException("Unknown package: " + packageName); 14865 } 14866 IBinder ksh = ks.getToken(); 14867 if (ksh instanceof KeySetHandle) { 14868 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14869 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 14870 } 14871 return false; 14872 } 14873 } 14874 14875 public void getUsageStatsIfNoPackageUsageInfo() { 14876 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 14877 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 14878 if (usm == null) { 14879 throw new IllegalStateException("UsageStatsManager must be initialized"); 14880 } 14881 long now = System.currentTimeMillis(); 14882 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 14883 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 14884 String packageName = entry.getKey(); 14885 PackageParser.Package pkg = mPackages.get(packageName); 14886 if (pkg == null) { 14887 continue; 14888 } 14889 UsageStats usage = entry.getValue(); 14890 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 14891 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 14892 } 14893 } 14894 } 14895 14896 /** 14897 * Check and throw if the given before/after packages would be considered a 14898 * downgrade. 14899 */ 14900 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 14901 throws PackageManagerException { 14902 if (after.versionCode < before.mVersionCode) { 14903 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14904 "Update version code " + after.versionCode + " is older than current " 14905 + before.mVersionCode); 14906 } else if (after.versionCode == before.mVersionCode) { 14907 if (after.baseRevisionCode < before.baseRevisionCode) { 14908 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14909 "Update base revision code " + after.baseRevisionCode 14910 + " is older than current " + before.baseRevisionCode); 14911 } 14912 14913 if (!ArrayUtils.isEmpty(after.splitNames)) { 14914 for (int i = 0; i < after.splitNames.length; i++) { 14915 final String splitName = after.splitNames[i]; 14916 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 14917 if (j != -1) { 14918 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 14919 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 14920 "Update split " + splitName + " revision code " 14921 + after.splitRevisionCodes[i] + " is older than current " 14922 + before.splitRevisionCodes[j]); 14923 } 14924 } 14925 } 14926 } 14927 } 14928 } 14929 14930 private static class MoveCallbacks extends Handler { 14931 private static final int MSG_CREATED = 1; 14932 private static final int MSG_STATUS_CHANGED = 2; 14933 14934 private final RemoteCallbackList<IPackageMoveObserver> 14935 mCallbacks = new RemoteCallbackList<>(); 14936 14937 private final SparseIntArray mLastStatus = new SparseIntArray(); 14938 14939 public MoveCallbacks(Looper looper) { 14940 super(looper); 14941 } 14942 14943 public void register(IPackageMoveObserver callback) { 14944 mCallbacks.register(callback); 14945 } 14946 14947 public void unregister(IPackageMoveObserver callback) { 14948 mCallbacks.unregister(callback); 14949 } 14950 14951 @Override 14952 public void handleMessage(Message msg) { 14953 final SomeArgs args = (SomeArgs) msg.obj; 14954 final int n = mCallbacks.beginBroadcast(); 14955 for (int i = 0; i < n; i++) { 14956 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 14957 try { 14958 invokeCallback(callback, msg.what, args); 14959 } catch (RemoteException ignored) { 14960 } 14961 } 14962 mCallbacks.finishBroadcast(); 14963 args.recycle(); 14964 } 14965 14966 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 14967 throws RemoteException { 14968 switch (what) { 14969 case MSG_CREATED: { 14970 callback.onCreated(args.argi1, (Bundle) args.arg2); 14971 break; 14972 } 14973 case MSG_STATUS_CHANGED: { 14974 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 14975 break; 14976 } 14977 } 14978 } 14979 14980 private void notifyCreated(int moveId, Bundle extras) { 14981 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 14982 14983 final SomeArgs args = SomeArgs.obtain(); 14984 args.argi1 = moveId; 14985 args.arg2 = extras; 14986 obtainMessage(MSG_CREATED, args).sendToTarget(); 14987 } 14988 14989 private void notifyStatusChanged(int moveId, int status) { 14990 notifyStatusChanged(moveId, status, -1); 14991 } 14992 14993 private void notifyStatusChanged(int moveId, int status, long estMillis) { 14994 Slog.v(TAG, "Move " + moveId + " status " + status); 14995 14996 final SomeArgs args = SomeArgs.obtain(); 14997 args.argi1 = moveId; 14998 args.argi2 = status; 14999 args.arg3 = estMillis; 15000 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 15001 15002 synchronized (mLastStatus) { 15003 mLastStatus.put(moveId, status); 15004 } 15005 } 15006 } 15007} 15008