PackageManagerService.java revision 3c13a2a5bc452777a785c1de74fff56a7cde9cdb
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.FIRST_APPLICATION_UID; 59import static android.os.Process.PACKAGE_INFO_GID; 60import static android.os.Process.SYSTEM_UID; 61import static android.system.OsConstants.O_CREAT; 62import static android.system.OsConstants.O_RDWR; 63import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 64import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER; 65import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 66import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 67import static com.android.internal.util.ArrayUtils.appendInt; 68import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 69import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 70import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 71import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 72import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 73 74import android.Manifest; 75import android.app.ActivityManager; 76import android.app.ActivityManagerNative; 77import android.app.AppGlobals; 78import android.app.IActivityManager; 79import android.app.admin.IDevicePolicyManager; 80import android.app.backup.IBackupManager; 81import android.app.usage.UsageStats; 82import android.app.usage.UsageStatsManager; 83import android.content.BroadcastReceiver; 84import android.content.ComponentName; 85import android.content.Context; 86import android.content.IIntentReceiver; 87import android.content.Intent; 88import android.content.IntentFilter; 89import android.content.IntentSender; 90import android.content.IntentSender.SendIntentException; 91import android.content.ServiceConnection; 92import android.content.pm.ActivityInfo; 93import android.content.pm.ApplicationInfo; 94import android.content.pm.FeatureInfo; 95import android.content.pm.IOnPermissionsChangeListener; 96import android.content.pm.IPackageDataObserver; 97import android.content.pm.IPackageDeleteObserver; 98import android.content.pm.IPackageDeleteObserver2; 99import android.content.pm.IPackageInstallObserver2; 100import android.content.pm.IPackageInstaller; 101import android.content.pm.IPackageManager; 102import android.content.pm.IPackageMoveObserver; 103import android.content.pm.IPackageStatsObserver; 104import android.content.pm.InstrumentationInfo; 105import android.content.pm.IntentFilterVerificationInfo; 106import android.content.pm.KeySet; 107import android.content.pm.ManifestDigest; 108import android.content.pm.PackageCleanItem; 109import android.content.pm.PackageInfo; 110import android.content.pm.PackageInfoLite; 111import android.content.pm.PackageInstaller; 112import android.content.pm.PackageManager; 113import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 114import android.content.pm.PackageParser; 115import android.content.pm.PackageParser.ActivityIntentInfo; 116import android.content.pm.PackageParser.PackageLite; 117import android.content.pm.PackageParser.PackageParserException; 118import android.content.pm.PackageStats; 119import android.content.pm.PackageUserState; 120import android.content.pm.ParceledListSlice; 121import android.content.pm.PermissionGroupInfo; 122import android.content.pm.PermissionInfo; 123import android.content.pm.ProviderInfo; 124import android.content.pm.ResolveInfo; 125import android.content.pm.ServiceInfo; 126import android.content.pm.Signature; 127import android.content.pm.UserInfo; 128import android.content.pm.VerificationParams; 129import android.content.pm.VerifierDeviceIdentity; 130import android.content.pm.VerifierInfo; 131import android.content.res.Resources; 132import android.hardware.display.DisplayManager; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.Environment; 139import android.os.Environment.UserEnvironment; 140import android.os.FileUtils; 141import android.os.Handler; 142import android.os.IBinder; 143import android.os.Looper; 144import android.os.Message; 145import android.os.Parcel; 146import android.os.ParcelFileDescriptor; 147import android.os.Process; 148import android.os.RemoteCallbackList; 149import android.os.RemoteException; 150import android.os.SELinux; 151import android.os.ServiceManager; 152import android.os.SystemClock; 153import android.os.SystemProperties; 154import android.os.UserHandle; 155import android.os.UserManager; 156import android.os.storage.IMountService; 157import android.os.storage.StorageEventListener; 158import android.os.storage.StorageManager; 159import android.os.storage.VolumeInfo; 160import android.os.storage.VolumeRecord; 161import android.security.KeyStore; 162import android.security.SystemKeyStore; 163import android.system.ErrnoException; 164import android.system.Os; 165import android.system.StructStat; 166import android.text.TextUtils; 167import android.text.format.DateUtils; 168import android.util.ArrayMap; 169import android.util.ArraySet; 170import android.util.AtomicFile; 171import android.util.DisplayMetrics; 172import android.util.EventLog; 173import android.util.ExceptionUtils; 174import android.util.Log; 175import android.util.LogPrinter; 176import android.util.MathUtils; 177import android.util.PrintStreamPrinter; 178import android.util.Slog; 179import android.util.SparseArray; 180import android.util.SparseBooleanArray; 181import android.util.SparseIntArray; 182import android.util.Xml; 183import android.view.Display; 184 185import dalvik.system.DexFile; 186import dalvik.system.VMRuntime; 187 188import libcore.io.IoUtils; 189import libcore.util.EmptyArray; 190 191import com.android.internal.R; 192import com.android.internal.app.IMediaContainerService; 193import com.android.internal.app.ResolverActivity; 194import com.android.internal.content.NativeLibraryHelper; 195import com.android.internal.content.PackageHelper; 196import com.android.internal.os.IParcelFileDescriptorFactory; 197import com.android.internal.os.SomeArgs; 198import com.android.internal.util.ArrayUtils; 199import com.android.internal.util.FastPrintWriter; 200import com.android.internal.util.FastXmlSerializer; 201import com.android.internal.util.IndentingPrintWriter; 202import com.android.internal.util.Preconditions; 203import com.android.server.EventLogTags; 204import com.android.server.FgThread; 205import com.android.server.IntentResolver; 206import com.android.server.LocalServices; 207import com.android.server.ServiceThread; 208import com.android.server.SystemConfig; 209import com.android.server.Watchdog; 210import com.android.server.pm.Settings.DatabaseVersion; 211import com.android.server.pm.PermissionsState.PermissionState; 212import com.android.server.storage.DeviceStorageMonitorInternal; 213 214import org.xmlpull.v1.XmlPullParser; 215import org.xmlpull.v1.XmlSerializer; 216 217import java.io.BufferedInputStream; 218import java.io.BufferedOutputStream; 219import java.io.BufferedReader; 220import java.io.ByteArrayInputStream; 221import java.io.ByteArrayOutputStream; 222import java.io.File; 223import java.io.FileDescriptor; 224import java.io.FileNotFoundException; 225import java.io.FileOutputStream; 226import java.io.FileReader; 227import java.io.FilenameFilter; 228import java.io.IOException; 229import java.io.InputStream; 230import java.io.PrintWriter; 231import java.nio.charset.StandardCharsets; 232import java.security.NoSuchAlgorithmException; 233import java.security.PublicKey; 234import java.security.cert.CertificateEncodingException; 235import java.security.cert.CertificateException; 236import java.text.SimpleDateFormat; 237import java.util.ArrayList; 238import java.util.Arrays; 239import java.util.Collection; 240import java.util.Collections; 241import java.util.Comparator; 242import java.util.Date; 243import java.util.Iterator; 244import java.util.List; 245import java.util.Map; 246import java.util.Objects; 247import java.util.Set; 248import java.util.concurrent.CountDownLatch; 249import java.util.concurrent.TimeUnit; 250import java.util.concurrent.atomic.AtomicBoolean; 251import java.util.concurrent.atomic.AtomicInteger; 252import java.util.concurrent.atomic.AtomicLong; 253 254/** 255 * Keep track of all those .apks everywhere. 256 * 257 * This is very central to the platform's security; please run the unit 258 * tests whenever making modifications here: 259 * 260mmm frameworks/base/tests/AndroidTests 261adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 262adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 263 * 264 * {@hide} 265 */ 266public class PackageManagerService extends IPackageManager.Stub { 267 static final String TAG = "PackageManager"; 268 static final boolean DEBUG_SETTINGS = false; 269 static final boolean DEBUG_PREFERRED = false; 270 static final boolean DEBUG_UPGRADE = false; 271 private static final boolean DEBUG_BACKUP = true; 272 private static final boolean DEBUG_INSTALL = false; 273 private static final boolean DEBUG_REMOVE = false; 274 private static final boolean DEBUG_BROADCASTS = false; 275 private static final boolean DEBUG_SHOW_INFO = false; 276 private static final boolean DEBUG_PACKAGE_INFO = false; 277 private static final boolean DEBUG_INTENT_MATCHING = false; 278 private static final boolean DEBUG_PACKAGE_SCANNING = false; 279 private static final boolean DEBUG_VERIFY = false; 280 private static final boolean DEBUG_DEXOPT = false; 281 private static final boolean DEBUG_ABI_SELECTION = false; 282 private static final boolean DEBUG_DOMAIN_VERIFICATION = false; 283 284 private static final int RADIO_UID = Process.PHONE_UID; 285 private static final int LOG_UID = Process.LOG_UID; 286 private static final int NFC_UID = Process.NFC_UID; 287 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 288 private static final int SHELL_UID = Process.SHELL_UID; 289 290 // Cap the size of permission trees that 3rd party apps can define 291 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 292 293 // Suffix used during package installation when copying/moving 294 // package apks to install directory. 295 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 296 297 static final int SCAN_NO_DEX = 1<<1; 298 static final int SCAN_FORCE_DEX = 1<<2; 299 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 300 static final int SCAN_NEW_INSTALL = 1<<4; 301 static final int SCAN_NO_PATHS = 1<<5; 302 static final int SCAN_UPDATE_TIME = 1<<6; 303 static final int SCAN_DEFER_DEX = 1<<7; 304 static final int SCAN_BOOTING = 1<<8; 305 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 306 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 307 static final int SCAN_REQUIRE_KNOWN = 1<<12; 308 static final int SCAN_MOVE = 1<<13; 309 310 static final int REMOVE_CHATTY = 1<<16; 311 312 private static final int[] EMPTY_INT_ARRAY = new int[0]; 313 314 /** 315 * Timeout (in milliseconds) after which the watchdog should declare that 316 * our handler thread is wedged. The usual default for such things is one 317 * minute but we sometimes do very lengthy I/O operations on this thread, 318 * such as installing multi-gigabyte applications, so ours needs to be longer. 319 */ 320 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 321 322 /** 323 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 324 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 325 * settings entry if available, otherwise we use the hardcoded default. If it's been 326 * more than this long since the last fstrim, we force one during the boot sequence. 327 * 328 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 329 * one gets run at the next available charging+idle time. This final mandatory 330 * no-fstrim check kicks in only of the other scheduling criteria is never met. 331 */ 332 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 333 334 /** 335 * Whether verification is enabled by default. 336 */ 337 private static final boolean DEFAULT_VERIFY_ENABLE = true; 338 339 /** 340 * The default maximum time to wait for the verification agent to return in 341 * milliseconds. 342 */ 343 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 344 345 /** 346 * The default response for package verification timeout. 347 * 348 * This can be either PackageManager.VERIFICATION_ALLOW or 349 * PackageManager.VERIFICATION_REJECT. 350 */ 351 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 352 353 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 354 355 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 356 DEFAULT_CONTAINER_PACKAGE, 357 "com.android.defcontainer.DefaultContainerService"); 358 359 private static final String KILL_APP_REASON_GIDS_CHANGED = 360 "permission grant or revoke changed gids"; 361 362 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 363 "permissions revoked"; 364 365 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 366 367 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 368 369 /** Permission grant: not grant the permission. */ 370 private static final int GRANT_DENIED = 1; 371 372 /** Permission grant: grant the permission as an install permission. */ 373 private static final int GRANT_INSTALL = 2; 374 375 /** Permission grant: grant the permission as an install permission for a legacy app. */ 376 private static final int GRANT_INSTALL_LEGACY = 3; 377 378 /** Permission grant: grant the permission as a runtime one. */ 379 private static final int GRANT_RUNTIME = 4; 380 381 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 382 private static final int GRANT_UPGRADE = 5; 383 384 final ServiceThread mHandlerThread; 385 386 final PackageHandler mHandler; 387 388 /** 389 * Messages for {@link #mHandler} that need to wait for system ready before 390 * being dispatched. 391 */ 392 private ArrayList<Message> mPostSystemReadyMessages; 393 394 final int mSdkVersion = Build.VERSION.SDK_INT; 395 396 final Context mContext; 397 final boolean mFactoryTest; 398 final boolean mOnlyCore; 399 final boolean mLazyDexOpt; 400 final long mDexOptLRUThresholdInMills; 401 final DisplayMetrics mMetrics; 402 final int mDefParseFlags; 403 final String[] mSeparateProcesses; 404 final boolean mIsUpgrade; 405 406 // This is where all application persistent data goes. 407 final File mAppDataDir; 408 409 // This is where all application persistent data goes for secondary users. 410 final File mUserAppDataDir; 411 412 /** The location for ASEC container files on internal storage. */ 413 final String mAsecInternalPath; 414 415 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 416 // LOCK HELD. Can be called with mInstallLock held. 417 final Installer mInstaller; 418 419 /** Directory where installed third-party apps stored */ 420 final File mAppInstallDir; 421 422 /** 423 * Directory to which applications installed internally have their 424 * 32 bit native libraries copied. 425 */ 426 private File mAppLib32InstallDir; 427 428 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 429 // apps. 430 final File mDrmAppPrivateInstallDir; 431 432 // ---------------------------------------------------------------- 433 434 // Lock for state used when installing and doing other long running 435 // operations. Methods that must be called with this lock held have 436 // the suffix "LI". 437 final Object mInstallLock = new Object(); 438 439 // ---------------------------------------------------------------- 440 441 // Keys are String (package name), values are Package. This also serves 442 // as the lock for the global state. Methods that must be called with 443 // this lock held have the prefix "LP". 444 final ArrayMap<String, PackageParser.Package> mPackages = 445 new ArrayMap<String, PackageParser.Package>(); 446 447 // Tracks available target package names -> overlay package paths. 448 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 449 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 450 451 final Settings mSettings; 452 boolean mRestoredSettings; 453 454 // System configuration read by SystemConfig. 455 final int[] mGlobalGids; 456 final SparseArray<ArraySet<String>> mSystemPermissions; 457 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 458 459 // If mac_permissions.xml was found for seinfo labeling. 460 boolean mFoundPolicyFile; 461 462 // If a recursive restorecon of /data/data/<pkg> is needed. 463 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 464 465 public static final class SharedLibraryEntry { 466 public final String path; 467 public final String apk; 468 469 SharedLibraryEntry(String _path, String _apk) { 470 path = _path; 471 apk = _apk; 472 } 473 } 474 475 // Currently known shared libraries. 476 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 477 new ArrayMap<String, SharedLibraryEntry>(); 478 479 // All available activities, for your resolving pleasure. 480 final ActivityIntentResolver mActivities = 481 new ActivityIntentResolver(); 482 483 // All available receivers, for your resolving pleasure. 484 final ActivityIntentResolver mReceivers = 485 new ActivityIntentResolver(); 486 487 // All available services, for your resolving pleasure. 488 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 489 490 // All available providers, for your resolving pleasure. 491 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 492 493 // Mapping from provider base names (first directory in content URI codePath) 494 // to the provider information. 495 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 496 new ArrayMap<String, PackageParser.Provider>(); 497 498 // Mapping from instrumentation class names to info about them. 499 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 500 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 501 502 // Mapping from permission names to info about them. 503 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 504 new ArrayMap<String, PackageParser.PermissionGroup>(); 505 506 // Packages whose data we have transfered into another package, thus 507 // should no longer exist. 508 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 509 510 // Broadcast actions that are only available to the system. 511 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 512 513 /** List of packages waiting for verification. */ 514 final SparseArray<PackageVerificationState> mPendingVerification 515 = new SparseArray<PackageVerificationState>(); 516 517 /** Set of packages associated with each app op permission. */ 518 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 519 520 final PackageInstallerService mInstallerService; 521 522 private final PackageDexOptimizer mPackageDexOptimizer; 523 524 private AtomicInteger mNextMoveId = new AtomicInteger(); 525 private final MoveCallbacks mMoveCallbacks; 526 527 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 528 529 // Cache of users who need badging. 530 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 531 532 /** Token for keys in mPendingVerification. */ 533 private int mPendingVerificationToken = 0; 534 535 volatile boolean mSystemReady; 536 volatile boolean mSafeMode; 537 volatile boolean mHasSystemUidErrors; 538 539 ApplicationInfo mAndroidApplication; 540 final ActivityInfo mResolveActivity = new ActivityInfo(); 541 final ResolveInfo mResolveInfo = new ResolveInfo(); 542 ComponentName mResolveComponentName; 543 PackageParser.Package mPlatformPackage; 544 ComponentName mCustomResolverComponentName; 545 546 boolean mResolverReplaced = false; 547 548 private final ComponentName mIntentFilterVerifierComponent; 549 private int mIntentFilterVerificationToken = 0; 550 551 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 552 = new SparseArray<IntentFilterVerificationState>(); 553 554 private interface IntentFilterVerifier<T extends IntentFilter> { 555 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 556 T filter, String packageName); 557 void startVerifications(int userId); 558 void receiveVerificationResponse(int verificationId); 559 } 560 561 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 562 private Context mContext; 563 private ComponentName mIntentFilterVerifierComponent; 564 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 565 566 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 567 mContext = context; 568 mIntentFilterVerifierComponent = verifierComponent; 569 } 570 571 private String getDefaultScheme() { 572 return IntentFilter.SCHEME_HTTPS; 573 } 574 575 @Override 576 public void startVerifications(int userId) { 577 // Launch verifications requests 578 int count = mCurrentIntentFilterVerifications.size(); 579 for (int n=0; n<count; n++) { 580 int verificationId = mCurrentIntentFilterVerifications.get(n); 581 final IntentFilterVerificationState ivs = 582 mIntentFilterVerificationStates.get(verificationId); 583 584 String packageName = ivs.getPackageName(); 585 586 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 587 final int filterCount = filters.size(); 588 ArraySet<String> domainsSet = new ArraySet<>(); 589 for (int m=0; m<filterCount; m++) { 590 PackageParser.ActivityIntentInfo filter = filters.get(m); 591 domainsSet.addAll(filter.getHostsList()); 592 } 593 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 594 synchronized (mPackages) { 595 if (mSettings.createIntentFilterVerificationIfNeededLPw( 596 packageName, domainsList) != null) { 597 scheduleWriteSettingsLocked(); 598 } 599 } 600 sendVerificationRequest(userId, verificationId, ivs); 601 } 602 mCurrentIntentFilterVerifications.clear(); 603 } 604 605 private void sendVerificationRequest(int userId, int verificationId, 606 IntentFilterVerificationState ivs) { 607 608 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 609 verificationIntent.putExtra( 610 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 611 verificationId); 612 verificationIntent.putExtra( 613 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 614 getDefaultScheme()); 615 verificationIntent.putExtra( 616 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 617 ivs.getHostsString()); 618 verificationIntent.putExtra( 619 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 620 ivs.getPackageName()); 621 verificationIntent.setComponent(mIntentFilterVerifierComponent); 622 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 623 624 UserHandle user = new UserHandle(userId); 625 mContext.sendBroadcastAsUser(verificationIntent, user); 626 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 627 "Sending IntenFilter verification broadcast"); 628 } 629 630 public void receiveVerificationResponse(int verificationId) { 631 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 632 633 final boolean verified = ivs.isVerified(); 634 635 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 636 final int count = filters.size(); 637 for (int n=0; n<count; n++) { 638 PackageParser.ActivityIntentInfo filter = filters.get(n); 639 filter.setVerified(verified); 640 641 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 642 + " verified with result:" + verified + " and hosts:" 643 + ivs.getHostsString()); 644 } 645 646 mIntentFilterVerificationStates.remove(verificationId); 647 648 final String packageName = ivs.getPackageName(); 649 IntentFilterVerificationInfo ivi = null; 650 651 synchronized (mPackages) { 652 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 653 } 654 if (ivi == null) { 655 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 656 + verificationId + " packageName:" + packageName); 657 return; 658 } 659 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 660 "Updating IntentFilterVerificationInfo for verificationId:" + verificationId); 661 662 synchronized (mPackages) { 663 if (verified) { 664 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 665 } else { 666 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 667 } 668 scheduleWriteSettingsLocked(); 669 670 final int userId = ivs.getUserId(); 671 if (userId != UserHandle.USER_ALL) { 672 final int userStatus = 673 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 674 675 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 676 boolean needUpdate = false; 677 678 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 679 // already been set by the User thru the Disambiguation dialog 680 switch (userStatus) { 681 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 682 if (verified) { 683 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 684 } else { 685 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 686 } 687 needUpdate = true; 688 break; 689 690 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 691 if (verified) { 692 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 693 needUpdate = true; 694 } 695 break; 696 697 default: 698 // Nothing to do 699 } 700 701 if (needUpdate) { 702 mSettings.updateIntentFilterVerificationStatusLPw( 703 packageName, updatedStatus, userId); 704 scheduleWritePackageRestrictionsLocked(userId); 705 } 706 } 707 } 708 } 709 710 @Override 711 public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 712 ActivityIntentInfo filter, String packageName) { 713 if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 714 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 715 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 716 "IntentFilter does not contain HTTP nor HTTPS data scheme"); 717 return false; 718 } 719 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 720 if (ivs == null) { 721 ivs = createDomainVerificationState(verifierId, userId, verificationId, 722 packageName); 723 } 724 if (!hasValidDomains(filter)) { 725 return false; 726 } 727 ivs.addFilter(filter); 728 return true; 729 } 730 731 private IntentFilterVerificationState createDomainVerificationState(int verifierId, 732 int userId, int verificationId, String packageName) { 733 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 734 verifierId, userId, packageName); 735 ivs.setPendingState(); 736 synchronized (mPackages) { 737 mIntentFilterVerificationStates.append(verificationId, ivs); 738 mCurrentIntentFilterVerifications.add(verificationId); 739 } 740 return ivs; 741 } 742 } 743 744 private static boolean hasValidDomains(ActivityIntentInfo filter) { 745 boolean hasHTTPorHTTPS = filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 746 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS); 747 if (!hasHTTPorHTTPS) { 748 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 749 "IntentFilter does not contain any HTTP or HTTPS data scheme"); 750 return false; 751 } 752 return true; 753 } 754 755 private IntentFilterVerifier mIntentFilterVerifier; 756 757 // Set of pending broadcasts for aggregating enable/disable of components. 758 static class PendingPackageBroadcasts { 759 // for each user id, a map of <package name -> components within that package> 760 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 761 762 public PendingPackageBroadcasts() { 763 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 764 } 765 766 public ArrayList<String> get(int userId, String packageName) { 767 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 768 return packages.get(packageName); 769 } 770 771 public void put(int userId, String packageName, ArrayList<String> components) { 772 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 773 packages.put(packageName, components); 774 } 775 776 public void remove(int userId, String packageName) { 777 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 778 if (packages != null) { 779 packages.remove(packageName); 780 } 781 } 782 783 public void remove(int userId) { 784 mUidMap.remove(userId); 785 } 786 787 public int userIdCount() { 788 return mUidMap.size(); 789 } 790 791 public int userIdAt(int n) { 792 return mUidMap.keyAt(n); 793 } 794 795 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 796 return mUidMap.get(userId); 797 } 798 799 public int size() { 800 // total number of pending broadcast entries across all userIds 801 int num = 0; 802 for (int i = 0; i< mUidMap.size(); i++) { 803 num += mUidMap.valueAt(i).size(); 804 } 805 return num; 806 } 807 808 public void clear() { 809 mUidMap.clear(); 810 } 811 812 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 813 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 814 if (map == null) { 815 map = new ArrayMap<String, ArrayList<String>>(); 816 mUidMap.put(userId, map); 817 } 818 return map; 819 } 820 } 821 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 822 823 // Service Connection to remote media container service to copy 824 // package uri's from external media onto secure containers 825 // or internal storage. 826 private IMediaContainerService mContainerService = null; 827 828 static final int SEND_PENDING_BROADCAST = 1; 829 static final int MCS_BOUND = 3; 830 static final int END_COPY = 4; 831 static final int INIT_COPY = 5; 832 static final int MCS_UNBIND = 6; 833 static final int START_CLEANING_PACKAGE = 7; 834 static final int FIND_INSTALL_LOC = 8; 835 static final int POST_INSTALL = 9; 836 static final int MCS_RECONNECT = 10; 837 static final int MCS_GIVE_UP = 11; 838 static final int UPDATED_MEDIA_STATUS = 12; 839 static final int WRITE_SETTINGS = 13; 840 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 841 static final int PACKAGE_VERIFIED = 15; 842 static final int CHECK_PENDING_VERIFICATION = 16; 843 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 844 static final int INTENT_FILTER_VERIFIED = 18; 845 846 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 847 848 // Delay time in millisecs 849 static final int BROADCAST_DELAY = 10 * 1000; 850 851 static UserManagerService sUserManager; 852 853 // Stores a list of users whose package restrictions file needs to be updated 854 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 855 856 final private DefaultContainerConnection mDefContainerConn = 857 new DefaultContainerConnection(); 858 class DefaultContainerConnection implements ServiceConnection { 859 public void onServiceConnected(ComponentName name, IBinder service) { 860 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 861 IMediaContainerService imcs = 862 IMediaContainerService.Stub.asInterface(service); 863 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 864 } 865 866 public void onServiceDisconnected(ComponentName name) { 867 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 868 } 869 }; 870 871 // Recordkeeping of restore-after-install operations that are currently in flight 872 // between the Package Manager and the Backup Manager 873 class PostInstallData { 874 public InstallArgs args; 875 public PackageInstalledInfo res; 876 877 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 878 args = _a; 879 res = _r; 880 } 881 }; 882 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 883 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 884 885 // backup/restore of preferred activity state 886 private static final String TAG_PREFERRED_BACKUP = "pa"; 887 888 private final String mRequiredVerifierPackage; 889 890 private final PackageUsage mPackageUsage = new PackageUsage(); 891 892 private class PackageUsage { 893 private static final int WRITE_INTERVAL 894 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 895 896 private final Object mFileLock = new Object(); 897 private final AtomicLong mLastWritten = new AtomicLong(0); 898 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 899 900 private boolean mIsHistoricalPackageUsageAvailable = true; 901 902 boolean isHistoricalPackageUsageAvailable() { 903 return mIsHistoricalPackageUsageAvailable; 904 } 905 906 void write(boolean force) { 907 if (force) { 908 writeInternal(); 909 return; 910 } 911 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 912 && !DEBUG_DEXOPT) { 913 return; 914 } 915 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 916 new Thread("PackageUsage_DiskWriter") { 917 @Override 918 public void run() { 919 try { 920 writeInternal(); 921 } finally { 922 mBackgroundWriteRunning.set(false); 923 } 924 } 925 }.start(); 926 } 927 } 928 929 private void writeInternal() { 930 synchronized (mPackages) { 931 synchronized (mFileLock) { 932 AtomicFile file = getFile(); 933 FileOutputStream f = null; 934 try { 935 f = file.startWrite(); 936 BufferedOutputStream out = new BufferedOutputStream(f); 937 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 938 StringBuilder sb = new StringBuilder(); 939 for (PackageParser.Package pkg : mPackages.values()) { 940 if (pkg.mLastPackageUsageTimeInMills == 0) { 941 continue; 942 } 943 sb.setLength(0); 944 sb.append(pkg.packageName); 945 sb.append(' '); 946 sb.append((long)pkg.mLastPackageUsageTimeInMills); 947 sb.append('\n'); 948 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 949 } 950 out.flush(); 951 file.finishWrite(f); 952 } catch (IOException e) { 953 if (f != null) { 954 file.failWrite(f); 955 } 956 Log.e(TAG, "Failed to write package usage times", e); 957 } 958 } 959 } 960 mLastWritten.set(SystemClock.elapsedRealtime()); 961 } 962 963 void readLP() { 964 synchronized (mFileLock) { 965 AtomicFile file = getFile(); 966 BufferedInputStream in = null; 967 try { 968 in = new BufferedInputStream(file.openRead()); 969 StringBuffer sb = new StringBuffer(); 970 while (true) { 971 String packageName = readToken(in, sb, ' '); 972 if (packageName == null) { 973 break; 974 } 975 String timeInMillisString = readToken(in, sb, '\n'); 976 if (timeInMillisString == null) { 977 throw new IOException("Failed to find last usage time for package " 978 + packageName); 979 } 980 PackageParser.Package pkg = mPackages.get(packageName); 981 if (pkg == null) { 982 continue; 983 } 984 long timeInMillis; 985 try { 986 timeInMillis = Long.parseLong(timeInMillisString.toString()); 987 } catch (NumberFormatException e) { 988 throw new IOException("Failed to parse " + timeInMillisString 989 + " as a long.", e); 990 } 991 pkg.mLastPackageUsageTimeInMills = timeInMillis; 992 } 993 } catch (FileNotFoundException expected) { 994 mIsHistoricalPackageUsageAvailable = false; 995 } catch (IOException e) { 996 Log.w(TAG, "Failed to read package usage times", e); 997 } finally { 998 IoUtils.closeQuietly(in); 999 } 1000 } 1001 mLastWritten.set(SystemClock.elapsedRealtime()); 1002 } 1003 1004 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1005 throws IOException { 1006 sb.setLength(0); 1007 while (true) { 1008 int ch = in.read(); 1009 if (ch == -1) { 1010 if (sb.length() == 0) { 1011 return null; 1012 } 1013 throw new IOException("Unexpected EOF"); 1014 } 1015 if (ch == endOfToken) { 1016 return sb.toString(); 1017 } 1018 sb.append((char)ch); 1019 } 1020 } 1021 1022 private AtomicFile getFile() { 1023 File dataDir = Environment.getDataDirectory(); 1024 File systemDir = new File(dataDir, "system"); 1025 File fname = new File(systemDir, "package-usage.list"); 1026 return new AtomicFile(fname); 1027 } 1028 } 1029 1030 class PackageHandler extends Handler { 1031 private boolean mBound = false; 1032 final ArrayList<HandlerParams> mPendingInstalls = 1033 new ArrayList<HandlerParams>(); 1034 1035 private boolean connectToService() { 1036 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1037 " DefaultContainerService"); 1038 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1039 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1040 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1041 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 1042 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1043 mBound = true; 1044 return true; 1045 } 1046 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1047 return false; 1048 } 1049 1050 private void disconnectService() { 1051 mContainerService = null; 1052 mBound = false; 1053 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1054 mContext.unbindService(mDefContainerConn); 1055 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1056 } 1057 1058 PackageHandler(Looper looper) { 1059 super(looper); 1060 } 1061 1062 public void handleMessage(Message msg) { 1063 try { 1064 doHandleMessage(msg); 1065 } finally { 1066 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1067 } 1068 } 1069 1070 void doHandleMessage(Message msg) { 1071 switch (msg.what) { 1072 case INIT_COPY: { 1073 HandlerParams params = (HandlerParams) msg.obj; 1074 int idx = mPendingInstalls.size(); 1075 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1076 // If a bind was already initiated we dont really 1077 // need to do anything. The pending install 1078 // will be processed later on. 1079 if (!mBound) { 1080 // If this is the only one pending we might 1081 // have to bind to the service again. 1082 if (!connectToService()) { 1083 Slog.e(TAG, "Failed to bind to media container service"); 1084 params.serviceError(); 1085 return; 1086 } else { 1087 // Once we bind to the service, the first 1088 // pending request will be processed. 1089 mPendingInstalls.add(idx, params); 1090 } 1091 } else { 1092 mPendingInstalls.add(idx, params); 1093 // Already bound to the service. Just make 1094 // sure we trigger off processing the first request. 1095 if (idx == 0) { 1096 mHandler.sendEmptyMessage(MCS_BOUND); 1097 } 1098 } 1099 break; 1100 } 1101 case MCS_BOUND: { 1102 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1103 if (msg.obj != null) { 1104 mContainerService = (IMediaContainerService) msg.obj; 1105 } 1106 if (mContainerService == null) { 1107 // Something seriously wrong. Bail out 1108 Slog.e(TAG, "Cannot bind to media container service"); 1109 for (HandlerParams params : mPendingInstalls) { 1110 // Indicate service bind error 1111 params.serviceError(); 1112 } 1113 mPendingInstalls.clear(); 1114 } else if (mPendingInstalls.size() > 0) { 1115 HandlerParams params = mPendingInstalls.get(0); 1116 if (params != null) { 1117 if (params.startCopy()) { 1118 // We are done... look for more work or to 1119 // go idle. 1120 if (DEBUG_SD_INSTALL) Log.i(TAG, 1121 "Checking for more work or unbind..."); 1122 // Delete pending install 1123 if (mPendingInstalls.size() > 0) { 1124 mPendingInstalls.remove(0); 1125 } 1126 if (mPendingInstalls.size() == 0) { 1127 if (mBound) { 1128 if (DEBUG_SD_INSTALL) Log.i(TAG, 1129 "Posting delayed MCS_UNBIND"); 1130 removeMessages(MCS_UNBIND); 1131 Message ubmsg = obtainMessage(MCS_UNBIND); 1132 // Unbind after a little delay, to avoid 1133 // continual thrashing. 1134 sendMessageDelayed(ubmsg, 10000); 1135 } 1136 } else { 1137 // There are more pending requests in queue. 1138 // Just post MCS_BOUND message to trigger processing 1139 // of next pending install. 1140 if (DEBUG_SD_INSTALL) Log.i(TAG, 1141 "Posting MCS_BOUND for next work"); 1142 mHandler.sendEmptyMessage(MCS_BOUND); 1143 } 1144 } 1145 } 1146 } else { 1147 // Should never happen ideally. 1148 Slog.w(TAG, "Empty queue"); 1149 } 1150 break; 1151 } 1152 case MCS_RECONNECT: { 1153 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1154 if (mPendingInstalls.size() > 0) { 1155 if (mBound) { 1156 disconnectService(); 1157 } 1158 if (!connectToService()) { 1159 Slog.e(TAG, "Failed to bind to media container service"); 1160 for (HandlerParams params : mPendingInstalls) { 1161 // Indicate service bind error 1162 params.serviceError(); 1163 } 1164 mPendingInstalls.clear(); 1165 } 1166 } 1167 break; 1168 } 1169 case MCS_UNBIND: { 1170 // If there is no actual work left, then time to unbind. 1171 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1172 1173 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1174 if (mBound) { 1175 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1176 1177 disconnectService(); 1178 } 1179 } else if (mPendingInstalls.size() > 0) { 1180 // There are more pending requests in queue. 1181 // Just post MCS_BOUND message to trigger processing 1182 // of next pending install. 1183 mHandler.sendEmptyMessage(MCS_BOUND); 1184 } 1185 1186 break; 1187 } 1188 case MCS_GIVE_UP: { 1189 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1190 mPendingInstalls.remove(0); 1191 break; 1192 } 1193 case SEND_PENDING_BROADCAST: { 1194 String packages[]; 1195 ArrayList<String> components[]; 1196 int size = 0; 1197 int uids[]; 1198 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1199 synchronized (mPackages) { 1200 if (mPendingBroadcasts == null) { 1201 return; 1202 } 1203 size = mPendingBroadcasts.size(); 1204 if (size <= 0) { 1205 // Nothing to be done. Just return 1206 return; 1207 } 1208 packages = new String[size]; 1209 components = new ArrayList[size]; 1210 uids = new int[size]; 1211 int i = 0; // filling out the above arrays 1212 1213 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1214 int packageUserId = mPendingBroadcasts.userIdAt(n); 1215 Iterator<Map.Entry<String, ArrayList<String>>> it 1216 = mPendingBroadcasts.packagesForUserId(packageUserId) 1217 .entrySet().iterator(); 1218 while (it.hasNext() && i < size) { 1219 Map.Entry<String, ArrayList<String>> ent = it.next(); 1220 packages[i] = ent.getKey(); 1221 components[i] = ent.getValue(); 1222 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1223 uids[i] = (ps != null) 1224 ? UserHandle.getUid(packageUserId, ps.appId) 1225 : -1; 1226 i++; 1227 } 1228 } 1229 size = i; 1230 mPendingBroadcasts.clear(); 1231 } 1232 // Send broadcasts 1233 for (int i = 0; i < size; i++) { 1234 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1235 } 1236 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1237 break; 1238 } 1239 case START_CLEANING_PACKAGE: { 1240 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1241 final String packageName = (String)msg.obj; 1242 final int userId = msg.arg1; 1243 final boolean andCode = msg.arg2 != 0; 1244 synchronized (mPackages) { 1245 if (userId == UserHandle.USER_ALL) { 1246 int[] users = sUserManager.getUserIds(); 1247 for (int user : users) { 1248 mSettings.addPackageToCleanLPw( 1249 new PackageCleanItem(user, packageName, andCode)); 1250 } 1251 } else { 1252 mSettings.addPackageToCleanLPw( 1253 new PackageCleanItem(userId, packageName, andCode)); 1254 } 1255 } 1256 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1257 startCleaningPackages(); 1258 } break; 1259 case POST_INSTALL: { 1260 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1261 PostInstallData data = mRunningInstalls.get(msg.arg1); 1262 mRunningInstalls.delete(msg.arg1); 1263 boolean deleteOld = false; 1264 1265 if (data != null) { 1266 InstallArgs args = data.args; 1267 PackageInstalledInfo res = data.res; 1268 1269 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1270 res.removedInfo.sendBroadcast(false, true, false); 1271 Bundle extras = new Bundle(1); 1272 extras.putInt(Intent.EXTRA_UID, res.uid); 1273 1274 // Now that we successfully installed the package, grant runtime 1275 // permissions if requested before broadcasting the install. 1276 if ((args.installFlags 1277 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { 1278 grantRequestedRuntimePermissions(res.pkg, 1279 args.user.getIdentifier()); 1280 } 1281 1282 // Determine the set of users who are adding this 1283 // package for the first time vs. those who are seeing 1284 // an update. 1285 int[] firstUsers; 1286 int[] updateUsers = new int[0]; 1287 if (res.origUsers == null || res.origUsers.length == 0) { 1288 firstUsers = res.newUsers; 1289 } else { 1290 firstUsers = new int[0]; 1291 for (int i=0; i<res.newUsers.length; i++) { 1292 int user = res.newUsers[i]; 1293 boolean isNew = true; 1294 for (int j=0; j<res.origUsers.length; j++) { 1295 if (res.origUsers[j] == user) { 1296 isNew = false; 1297 break; 1298 } 1299 } 1300 if (isNew) { 1301 int[] newFirst = new int[firstUsers.length+1]; 1302 System.arraycopy(firstUsers, 0, newFirst, 0, 1303 firstUsers.length); 1304 newFirst[firstUsers.length] = user; 1305 firstUsers = newFirst; 1306 } else { 1307 int[] newUpdate = new int[updateUsers.length+1]; 1308 System.arraycopy(updateUsers, 0, newUpdate, 0, 1309 updateUsers.length); 1310 newUpdate[updateUsers.length] = user; 1311 updateUsers = newUpdate; 1312 } 1313 } 1314 } 1315 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1316 res.pkg.applicationInfo.packageName, 1317 extras, null, null, firstUsers); 1318 final boolean update = res.removedInfo.removedPackage != null; 1319 if (update) { 1320 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1321 } 1322 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1323 res.pkg.applicationInfo.packageName, 1324 extras, null, null, updateUsers); 1325 if (update) { 1326 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1327 res.pkg.applicationInfo.packageName, 1328 extras, null, null, updateUsers); 1329 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1330 null, null, 1331 res.pkg.applicationInfo.packageName, null, updateUsers); 1332 1333 // treat asec-hosted packages like removable media on upgrade 1334 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1335 if (DEBUG_INSTALL) { 1336 Slog.i(TAG, "upgrading pkg " + res.pkg 1337 + " is ASEC-hosted -> AVAILABLE"); 1338 } 1339 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1340 ArrayList<String> pkgList = new ArrayList<String>(1); 1341 pkgList.add(res.pkg.applicationInfo.packageName); 1342 sendResourcesChangedBroadcast(true, true, 1343 pkgList,uidArray, null); 1344 } 1345 } 1346 if (res.removedInfo.args != null) { 1347 // Remove the replaced package's older resources safely now 1348 deleteOld = true; 1349 } 1350 1351 // Log current value of "unknown sources" setting 1352 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1353 getUnknownSourcesSettings()); 1354 } 1355 // Force a gc to clear up things 1356 Runtime.getRuntime().gc(); 1357 // We delete after a gc for applications on sdcard. 1358 if (deleteOld) { 1359 synchronized (mInstallLock) { 1360 res.removedInfo.args.doPostDeleteLI(true); 1361 } 1362 } 1363 if (args.observer != null) { 1364 try { 1365 Bundle extras = extrasForInstallResult(res); 1366 args.observer.onPackageInstalled(res.name, res.returnCode, 1367 res.returnMsg, extras); 1368 } catch (RemoteException e) { 1369 Slog.i(TAG, "Observer no longer exists."); 1370 } 1371 } 1372 } else { 1373 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1374 } 1375 } break; 1376 case UPDATED_MEDIA_STATUS: { 1377 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1378 boolean reportStatus = msg.arg1 == 1; 1379 boolean doGc = msg.arg2 == 1; 1380 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1381 if (doGc) { 1382 // Force a gc to clear up stale containers. 1383 Runtime.getRuntime().gc(); 1384 } 1385 if (msg.obj != null) { 1386 @SuppressWarnings("unchecked") 1387 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1388 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1389 // Unload containers 1390 unloadAllContainers(args); 1391 } 1392 if (reportStatus) { 1393 try { 1394 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1395 PackageHelper.getMountService().finishMediaUpdate(); 1396 } catch (RemoteException e) { 1397 Log.e(TAG, "MountService not running?"); 1398 } 1399 } 1400 } break; 1401 case WRITE_SETTINGS: { 1402 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1403 synchronized (mPackages) { 1404 removeMessages(WRITE_SETTINGS); 1405 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1406 mSettings.writeLPr(); 1407 mDirtyUsers.clear(); 1408 } 1409 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1410 } break; 1411 case WRITE_PACKAGE_RESTRICTIONS: { 1412 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1413 synchronized (mPackages) { 1414 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1415 for (int userId : mDirtyUsers) { 1416 mSettings.writePackageRestrictionsLPr(userId); 1417 } 1418 mDirtyUsers.clear(); 1419 } 1420 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1421 } break; 1422 case CHECK_PENDING_VERIFICATION: { 1423 final int verificationId = msg.arg1; 1424 final PackageVerificationState state = mPendingVerification.get(verificationId); 1425 1426 if ((state != null) && !state.timeoutExtended()) { 1427 final InstallArgs args = state.getInstallArgs(); 1428 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1429 1430 Slog.i(TAG, "Verification timed out for " + originUri); 1431 mPendingVerification.remove(verificationId); 1432 1433 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1434 1435 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1436 Slog.i(TAG, "Continuing with installation of " + originUri); 1437 state.setVerifierResponse(Binder.getCallingUid(), 1438 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1439 broadcastPackageVerified(verificationId, originUri, 1440 PackageManager.VERIFICATION_ALLOW, 1441 state.getInstallArgs().getUser()); 1442 try { 1443 ret = args.copyApk(mContainerService, true); 1444 } catch (RemoteException e) { 1445 Slog.e(TAG, "Could not contact the ContainerService"); 1446 } 1447 } else { 1448 broadcastPackageVerified(verificationId, originUri, 1449 PackageManager.VERIFICATION_REJECT, 1450 state.getInstallArgs().getUser()); 1451 } 1452 1453 processPendingInstall(args, ret); 1454 mHandler.sendEmptyMessage(MCS_UNBIND); 1455 } 1456 break; 1457 } 1458 case PACKAGE_VERIFIED: { 1459 final int verificationId = msg.arg1; 1460 1461 final PackageVerificationState state = mPendingVerification.get(verificationId); 1462 if (state == null) { 1463 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1464 break; 1465 } 1466 1467 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1468 1469 state.setVerifierResponse(response.callerUid, response.code); 1470 1471 if (state.isVerificationComplete()) { 1472 mPendingVerification.remove(verificationId); 1473 1474 final InstallArgs args = state.getInstallArgs(); 1475 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1476 1477 int ret; 1478 if (state.isInstallAllowed()) { 1479 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1480 broadcastPackageVerified(verificationId, originUri, 1481 response.code, state.getInstallArgs().getUser()); 1482 try { 1483 ret = args.copyApk(mContainerService, true); 1484 } catch (RemoteException e) { 1485 Slog.e(TAG, "Could not contact the ContainerService"); 1486 } 1487 } else { 1488 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1489 } 1490 1491 processPendingInstall(args, ret); 1492 1493 mHandler.sendEmptyMessage(MCS_UNBIND); 1494 } 1495 1496 break; 1497 } 1498 case START_INTENT_FILTER_VERIFICATIONS: { 1499 int userId = msg.arg1; 1500 int verifierUid = msg.arg2; 1501 PackageParser.Package pkg = (PackageParser.Package)msg.obj; 1502 1503 verifyIntentFiltersIfNeeded(userId, verifierUid, pkg); 1504 break; 1505 } 1506 case INTENT_FILTER_VERIFIED: { 1507 final int verificationId = msg.arg1; 1508 1509 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1510 verificationId); 1511 if (state == null) { 1512 Slog.w(TAG, "Invalid IntentFilter verification token " 1513 + verificationId + " received"); 1514 break; 1515 } 1516 1517 final int userId = state.getUserId(); 1518 1519 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1520 "Processing IntentFilter verification with token:" 1521 + verificationId + " and userId:" + userId); 1522 1523 final IntentFilterVerificationResponse response = 1524 (IntentFilterVerificationResponse) msg.obj; 1525 1526 state.setVerifierResponse(response.callerUid, response.code); 1527 1528 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1529 "IntentFilter verification with token:" + verificationId 1530 + " and userId:" + userId 1531 + " is settings verifier response with response code:" 1532 + response.code); 1533 1534 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1535 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1536 + response.getFailedDomainsString()); 1537 } 1538 1539 if (state.isVerificationComplete()) { 1540 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1541 } else { 1542 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1543 "IntentFilter verification with token:" + verificationId 1544 + " was not said to be complete"); 1545 } 1546 1547 break; 1548 } 1549 } 1550 } 1551 } 1552 1553 private StorageEventListener mStorageListener = new StorageEventListener() { 1554 @Override 1555 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1556 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1557 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1558 // TODO: ensure that private directories exist for all active users 1559 // TODO: remove user data whose serial number doesn't match 1560 loadPrivatePackages(vol); 1561 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1562 unloadPrivatePackages(vol); 1563 } 1564 } 1565 1566 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1567 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1568 updateExternalMediaStatus(true, false); 1569 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1570 updateExternalMediaStatus(false, false); 1571 } 1572 } 1573 } 1574 1575 @Override 1576 public void onVolumeForgotten(String fsUuid) { 1577 // TODO: remove all packages hosted on this uuid 1578 } 1579 }; 1580 1581 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) { 1582 if (userId >= UserHandle.USER_OWNER) { 1583 grantRequestedRuntimePermissionsForUser(pkg, userId); 1584 } else if (userId == UserHandle.USER_ALL) { 1585 for (int someUserId : UserManagerService.getInstance().getUserIds()) { 1586 grantRequestedRuntimePermissionsForUser(pkg, someUserId); 1587 } 1588 } 1589 } 1590 1591 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) { 1592 SettingBase sb = (SettingBase) pkg.mExtras; 1593 if (sb == null) { 1594 return; 1595 } 1596 1597 PermissionsState permissionsState = sb.getPermissionsState(); 1598 1599 for (String permission : pkg.requestedPermissions) { 1600 BasePermission bp = mSettings.mPermissions.get(permission); 1601 if (bp != null && bp.isRuntime()) { 1602 permissionsState.grantRuntimePermission(bp, userId); 1603 } 1604 } 1605 } 1606 1607 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1608 Bundle extras = null; 1609 switch (res.returnCode) { 1610 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1611 extras = new Bundle(); 1612 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1613 res.origPermission); 1614 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1615 res.origPackage); 1616 break; 1617 } 1618 case PackageManager.INSTALL_SUCCEEDED: { 1619 extras = new Bundle(); 1620 extras.putBoolean(Intent.EXTRA_REPLACING, 1621 res.removedInfo != null && res.removedInfo.removedPackage != null); 1622 break; 1623 } 1624 } 1625 return extras; 1626 } 1627 1628 void scheduleWriteSettingsLocked() { 1629 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1630 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1631 } 1632 } 1633 1634 void scheduleWritePackageRestrictionsLocked(int userId) { 1635 if (!sUserManager.exists(userId)) return; 1636 mDirtyUsers.add(userId); 1637 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1638 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1639 } 1640 } 1641 1642 public static PackageManagerService main(Context context, Installer installer, 1643 boolean factoryTest, boolean onlyCore) { 1644 PackageManagerService m = new PackageManagerService(context, installer, 1645 factoryTest, onlyCore); 1646 ServiceManager.addService("package", m); 1647 return m; 1648 } 1649 1650 static String[] splitString(String str, char sep) { 1651 int count = 1; 1652 int i = 0; 1653 while ((i=str.indexOf(sep, i)) >= 0) { 1654 count++; 1655 i++; 1656 } 1657 1658 String[] res = new String[count]; 1659 i=0; 1660 count = 0; 1661 int lastI=0; 1662 while ((i=str.indexOf(sep, i)) >= 0) { 1663 res[count] = str.substring(lastI, i); 1664 count++; 1665 i++; 1666 lastI = i; 1667 } 1668 res[count] = str.substring(lastI, str.length()); 1669 return res; 1670 } 1671 1672 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1673 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1674 Context.DISPLAY_SERVICE); 1675 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1676 } 1677 1678 public PackageManagerService(Context context, Installer installer, 1679 boolean factoryTest, boolean onlyCore) { 1680 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1681 SystemClock.uptimeMillis()); 1682 1683 if (mSdkVersion <= 0) { 1684 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1685 } 1686 1687 mContext = context; 1688 mFactoryTest = factoryTest; 1689 mOnlyCore = onlyCore; 1690 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1691 mMetrics = new DisplayMetrics(); 1692 mSettings = new Settings(mPackages); 1693 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1694 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1695 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1696 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1697 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1698 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1699 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1700 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1701 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1702 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1703 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1704 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 1705 1706 // TODO: add a property to control this? 1707 long dexOptLRUThresholdInMinutes; 1708 if (mLazyDexOpt) { 1709 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1710 } else { 1711 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1712 } 1713 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1714 1715 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1716 if (separateProcesses != null && separateProcesses.length() > 0) { 1717 if ("*".equals(separateProcesses)) { 1718 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1719 mSeparateProcesses = null; 1720 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1721 } else { 1722 mDefParseFlags = 0; 1723 mSeparateProcesses = separateProcesses.split(","); 1724 Slog.w(TAG, "Running with debug.separate_processes: " 1725 + separateProcesses); 1726 } 1727 } else { 1728 mDefParseFlags = 0; 1729 mSeparateProcesses = null; 1730 } 1731 1732 mInstaller = installer; 1733 mPackageDexOptimizer = new PackageDexOptimizer(this); 1734 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 1735 1736 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 1737 FgThread.get().getLooper()); 1738 1739 getDefaultDisplayMetrics(context, mMetrics); 1740 1741 SystemConfig systemConfig = SystemConfig.getInstance(); 1742 mGlobalGids = systemConfig.getGlobalGids(); 1743 mSystemPermissions = systemConfig.getSystemPermissions(); 1744 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1745 1746 synchronized (mInstallLock) { 1747 // writer 1748 synchronized (mPackages) { 1749 mHandlerThread = new ServiceThread(TAG, 1750 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1751 mHandlerThread.start(); 1752 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1753 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1754 1755 File dataDir = Environment.getDataDirectory(); 1756 mAppDataDir = new File(dataDir, "data"); 1757 mAppInstallDir = new File(dataDir, "app"); 1758 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1759 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1760 mUserAppDataDir = new File(dataDir, "user"); 1761 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1762 1763 sUserManager = new UserManagerService(context, this, 1764 mInstallLock, mPackages); 1765 1766 // Propagate permission configuration in to package manager. 1767 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1768 = systemConfig.getPermissions(); 1769 for (int i=0; i<permConfig.size(); i++) { 1770 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1771 BasePermission bp = mSettings.mPermissions.get(perm.name); 1772 if (bp == null) { 1773 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1774 mSettings.mPermissions.put(perm.name, bp); 1775 } 1776 if (perm.gids != null) { 1777 bp.setGids(perm.gids, perm.perUser); 1778 } 1779 } 1780 1781 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1782 for (int i=0; i<libConfig.size(); i++) { 1783 mSharedLibraries.put(libConfig.keyAt(i), 1784 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1785 } 1786 1787 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1788 1789 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1790 mSdkVersion, mOnlyCore); 1791 1792 String customResolverActivity = Resources.getSystem().getString( 1793 R.string.config_customResolverActivity); 1794 if (TextUtils.isEmpty(customResolverActivity)) { 1795 customResolverActivity = null; 1796 } else { 1797 mCustomResolverComponentName = ComponentName.unflattenFromString( 1798 customResolverActivity); 1799 } 1800 1801 long startTime = SystemClock.uptimeMillis(); 1802 1803 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1804 startTime); 1805 1806 // Set flag to monitor and not change apk file paths when 1807 // scanning install directories. 1808 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1809 1810 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1811 1812 /** 1813 * Add everything in the in the boot class path to the 1814 * list of process files because dexopt will have been run 1815 * if necessary during zygote startup. 1816 */ 1817 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1818 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1819 1820 if (bootClassPath != null) { 1821 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1822 for (String element : bootClassPathElements) { 1823 alreadyDexOpted.add(element); 1824 } 1825 } else { 1826 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1827 } 1828 1829 if (systemServerClassPath != null) { 1830 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1831 for (String element : systemServerClassPathElements) { 1832 alreadyDexOpted.add(element); 1833 } 1834 } else { 1835 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 1836 } 1837 1838 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 1839 final String[] dexCodeInstructionSets = 1840 getDexCodeInstructionSets( 1841 allInstructionSets.toArray(new String[allInstructionSets.size()])); 1842 1843 /** 1844 * Ensure all external libraries have had dexopt run on them. 1845 */ 1846 if (mSharedLibraries.size() > 0) { 1847 // NOTE: For now, we're compiling these system "shared libraries" 1848 // (and framework jars) into all available architectures. It's possible 1849 // to compile them only when we come across an app that uses them (there's 1850 // already logic for that in scanPackageLI) but that adds some complexity. 1851 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1852 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1853 final String lib = libEntry.path; 1854 if (lib == null) { 1855 continue; 1856 } 1857 1858 try { 1859 int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); 1860 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1861 alreadyDexOpted.add(lib); 1862 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 1863 } 1864 } catch (FileNotFoundException e) { 1865 Slog.w(TAG, "Library not found: " + lib); 1866 } catch (IOException e) { 1867 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1868 + e.getMessage()); 1869 } 1870 } 1871 } 1872 } 1873 1874 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1875 1876 // Gross hack for now: we know this file doesn't contain any 1877 // code, so don't dexopt it to avoid the resulting log spew. 1878 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1879 1880 // Gross hack for now: we know this file is only part of 1881 // the boot class path for art, so don't dexopt it to 1882 // avoid the resulting log spew. 1883 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1884 1885 /** 1886 * There are a number of commands implemented in Java, which 1887 * we currently need to do the dexopt on so that they can be 1888 * run from a non-root shell. 1889 */ 1890 String[] frameworkFiles = frameworkDir.list(); 1891 if (frameworkFiles != null) { 1892 // TODO: We could compile these only for the most preferred ABI. We should 1893 // first double check that the dex files for these commands are not referenced 1894 // by other system apps. 1895 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1896 for (int i=0; i<frameworkFiles.length; i++) { 1897 File libPath = new File(frameworkDir, frameworkFiles[i]); 1898 String path = libPath.getPath(); 1899 // Skip the file if we already did it. 1900 if (alreadyDexOpted.contains(path)) { 1901 continue; 1902 } 1903 // Skip the file if it is not a type we want to dexopt. 1904 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1905 continue; 1906 } 1907 try { 1908 int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); 1909 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 1910 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); 1911 } 1912 } catch (FileNotFoundException e) { 1913 Slog.w(TAG, "Jar not found: " + path); 1914 } catch (IOException e) { 1915 Slog.w(TAG, "Exception reading jar: " + path, e); 1916 } 1917 } 1918 } 1919 } 1920 1921 // Collect vendor overlay packages. 1922 // (Do this before scanning any apps.) 1923 // For security and version matching reason, only consider 1924 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1925 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1926 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1927 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 1928 1929 // Find base frameworks (resource packages without code). 1930 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1931 | PackageParser.PARSE_IS_SYSTEM_DIR 1932 | PackageParser.PARSE_IS_PRIVILEGED, 1933 scanFlags | SCAN_NO_DEX, 0); 1934 1935 // Collected privileged system packages. 1936 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1937 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1938 | PackageParser.PARSE_IS_SYSTEM_DIR 1939 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 1940 1941 // Collect ordinary system packages. 1942 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1943 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1944 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1945 1946 // Collect all vendor packages. 1947 File vendorAppDir = new File("/vendor/app"); 1948 try { 1949 vendorAppDir = vendorAppDir.getCanonicalFile(); 1950 } catch (IOException e) { 1951 // failed to look up canonical path, continue with original one 1952 } 1953 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1954 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1955 1956 // Collect all OEM packages. 1957 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 1958 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 1959 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1960 1961 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1962 mInstaller.moveFiles(); 1963 1964 // Prune any system packages that no longer exist. 1965 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1966 final ArrayMap<String, File> expectingBetter = new ArrayMap<>(); 1967 if (!mOnlyCore) { 1968 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1969 while (psit.hasNext()) { 1970 PackageSetting ps = psit.next(); 1971 1972 /* 1973 * If this is not a system app, it can't be a 1974 * disable system app. 1975 */ 1976 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1977 continue; 1978 } 1979 1980 /* 1981 * If the package is scanned, it's not erased. 1982 */ 1983 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1984 if (scannedPkg != null) { 1985 /* 1986 * If the system app is both scanned and in the 1987 * disabled packages list, then it must have been 1988 * added via OTA. Remove it from the currently 1989 * scanned package so the previously user-installed 1990 * application can be scanned. 1991 */ 1992 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1993 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 1994 + ps.name + "; removing system app. Last known codePath=" 1995 + ps.codePathString + ", installStatus=" + ps.installStatus 1996 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 1997 + scannedPkg.mVersionCode); 1998 removePackageLI(ps, true); 1999 expectingBetter.put(ps.name, ps.codePath); 2000 } 2001 2002 continue; 2003 } 2004 2005 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2006 psit.remove(); 2007 logCriticalInfo(Log.WARN, "System package " + ps.name 2008 + " no longer exists; wiping its data"); 2009 removeDataDirsLI(null, ps.name); 2010 } else { 2011 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2012 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2013 possiblyDeletedUpdatedSystemApps.add(ps.name); 2014 } 2015 } 2016 } 2017 } 2018 2019 //look for any incomplete package installations 2020 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2021 //clean up list 2022 for(int i = 0; i < deletePkgsList.size(); i++) { 2023 //clean up here 2024 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2025 } 2026 //delete tmp files 2027 deleteTempPackageFiles(); 2028 2029 // Remove any shared userIDs that have no associated packages 2030 mSettings.pruneSharedUsersLPw(); 2031 2032 if (!mOnlyCore) { 2033 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2034 SystemClock.uptimeMillis()); 2035 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2036 2037 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2038 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2039 2040 /** 2041 * Remove disable package settings for any updated system 2042 * apps that were removed via an OTA. If they're not a 2043 * previously-updated app, remove them completely. 2044 * Otherwise, just revoke their system-level permissions. 2045 */ 2046 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2047 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2048 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2049 2050 String msg; 2051 if (deletedPkg == null) { 2052 msg = "Updated system package " + deletedAppName 2053 + " no longer exists; wiping its data"; 2054 removeDataDirsLI(null, deletedAppName); 2055 } else { 2056 msg = "Updated system app + " + deletedAppName 2057 + " no longer present; removing system privileges for " 2058 + deletedAppName; 2059 2060 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2061 2062 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2063 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2064 } 2065 logCriticalInfo(Log.WARN, msg); 2066 } 2067 2068 /** 2069 * Make sure all system apps that we expected to appear on 2070 * the userdata partition actually showed up. If they never 2071 * appeared, crawl back and revive the system version. 2072 */ 2073 for (int i = 0; i < expectingBetter.size(); i++) { 2074 final String packageName = expectingBetter.keyAt(i); 2075 if (!mPackages.containsKey(packageName)) { 2076 final File scanFile = expectingBetter.valueAt(i); 2077 2078 logCriticalInfo(Log.WARN, "Expected better " + packageName 2079 + " but never showed up; reverting to system"); 2080 2081 final int reparseFlags; 2082 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2083 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2084 | PackageParser.PARSE_IS_SYSTEM_DIR 2085 | PackageParser.PARSE_IS_PRIVILEGED; 2086 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2087 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2088 | PackageParser.PARSE_IS_SYSTEM_DIR; 2089 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2090 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2091 | PackageParser.PARSE_IS_SYSTEM_DIR; 2092 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2093 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2094 | PackageParser.PARSE_IS_SYSTEM_DIR; 2095 } else { 2096 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2097 continue; 2098 } 2099 2100 mSettings.enableSystemPackageLPw(packageName); 2101 2102 try { 2103 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null); 2104 } catch (PackageManagerException e) { 2105 Slog.e(TAG, "Failed to parse original system package: " 2106 + e.getMessage()); 2107 } 2108 } 2109 } 2110 } 2111 2112 // Now that we know all of the shared libraries, update all clients to have 2113 // the correct library paths. 2114 updateAllSharedLibrariesLPw(); 2115 2116 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2117 // NOTE: We ignore potential failures here during a system scan (like 2118 // the rest of the commands above) because there's precious little we 2119 // can do about it. A settings error is reported, though. 2120 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2121 false /* force dexopt */, false /* defer dexopt */); 2122 } 2123 2124 // Now that we know all the packages we are keeping, 2125 // read and update their last usage times. 2126 mPackageUsage.readLP(); 2127 2128 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2129 SystemClock.uptimeMillis()); 2130 Slog.i(TAG, "Time to scan packages: " 2131 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2132 + " seconds"); 2133 2134 // If the platform SDK has changed since the last time we booted, 2135 // we need to re-grant app permission to catch any new ones that 2136 // appear. This is really a hack, and means that apps can in some 2137 // cases get permissions that the user didn't initially explicitly 2138 // allow... it would be nice to have some better way to handle 2139 // this situation. 2140 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 2141 != mSdkVersion; 2142 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 2143 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 2144 + "; regranting permissions for internal storage"); 2145 mSettings.mInternalSdkPlatform = mSdkVersion; 2146 2147 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 2148 | (regrantPermissions 2149 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 2150 : 0)); 2151 2152 // If this is the first boot, and it is a normal boot, then 2153 // we need to initialize the default preferred apps. 2154 if (!mRestoredSettings && !onlyCore) { 2155 mSettings.readDefaultPreferredAppsLPw(this, 0); 2156 } 2157 2158 // If this is first boot after an OTA, and a normal boot, then 2159 // we need to clear code cache directories. 2160 mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint); 2161 if (mIsUpgrade && !onlyCore) { 2162 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2163 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2164 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2165 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2166 } 2167 mSettings.mFingerprint = Build.FINGERPRINT; 2168 } 2169 2170 primeDomainVerificationsLPw(); 2171 checkDefaultBrowser(); 2172 2173 // All the changes are done during package scanning. 2174 mSettings.updateInternalDatabaseVersion(); 2175 2176 // can downgrade to reader 2177 mSettings.writeLPr(); 2178 2179 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2180 SystemClock.uptimeMillis()); 2181 2182 mRequiredVerifierPackage = getRequiredVerifierLPr(); 2183 2184 mInstallerService = new PackageInstallerService(context, this); 2185 2186 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2187 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2188 mIntentFilterVerifierComponent); 2189 2190 } // synchronized (mPackages) 2191 } // synchronized (mInstallLock) 2192 2193 // Now after opening every single application zip, make sure they 2194 // are all flushed. Not really needed, but keeps things nice and 2195 // tidy. 2196 Runtime.getRuntime().gc(); 2197 } 2198 2199 @Override 2200 public boolean isFirstBoot() { 2201 return !mRestoredSettings; 2202 } 2203 2204 @Override 2205 public boolean isOnlyCoreApps() { 2206 return mOnlyCore; 2207 } 2208 2209 @Override 2210 public boolean isUpgrade() { 2211 return mIsUpgrade; 2212 } 2213 2214 private String getRequiredVerifierLPr() { 2215 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2216 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2217 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 2218 2219 String requiredVerifier = null; 2220 2221 final int N = receivers.size(); 2222 for (int i = 0; i < N; i++) { 2223 final ResolveInfo info = receivers.get(i); 2224 2225 if (info.activityInfo == null) { 2226 continue; 2227 } 2228 2229 final String packageName = info.activityInfo.packageName; 2230 2231 if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 2232 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2233 continue; 2234 } 2235 2236 if (requiredVerifier != null) { 2237 throw new RuntimeException("There can be only one required verifier"); 2238 } 2239 2240 requiredVerifier = packageName; 2241 } 2242 2243 return requiredVerifier; 2244 } 2245 2246 private ComponentName getIntentFilterVerifierComponentNameLPr() { 2247 final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2248 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 2249 PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */); 2250 2251 ComponentName verifierComponentName = null; 2252 2253 int priority = -1000; 2254 final int N = receivers.size(); 2255 for (int i = 0; i < N; i++) { 2256 final ResolveInfo info = receivers.get(i); 2257 2258 if (info.activityInfo == null) { 2259 continue; 2260 } 2261 2262 final String packageName = info.activityInfo.packageName; 2263 2264 final PackageSetting ps = mSettings.mPackages.get(packageName); 2265 if (ps == null) { 2266 continue; 2267 } 2268 2269 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2270 packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) { 2271 continue; 2272 } 2273 2274 // Select the IntentFilterVerifier with the highest priority 2275 if (priority < info.priority) { 2276 priority = info.priority; 2277 verifierComponentName = new ComponentName(packageName, info.activityInfo.name); 2278 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Selecting IntentFilterVerifier: " 2279 + verifierComponentName + " with priority: " + info.priority); 2280 } 2281 } 2282 2283 return verifierComponentName; 2284 } 2285 2286 private void primeDomainVerificationsLPw() { 2287 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Start priming domain verifications"); 2288 boolean updated = false; 2289 ArraySet<String> allHostsSet = new ArraySet<>(); 2290 for (PackageParser.Package pkg : mPackages.values()) { 2291 final String packageName = pkg.packageName; 2292 if (!hasDomainURLs(pkg)) { 2293 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "No priming domain verifications for " + 2294 "package with no domain URLs: " + packageName); 2295 continue; 2296 } 2297 if (!pkg.isSystemApp()) { 2298 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 2299 "No priming domain verifications for a non system package : " + 2300 packageName); 2301 continue; 2302 } 2303 for (PackageParser.Activity a : pkg.activities) { 2304 for (ActivityIntentInfo filter : a.intents) { 2305 if (hasValidDomains(filter)) { 2306 allHostsSet.addAll(filter.getHostsList()); 2307 } 2308 } 2309 } 2310 if (allHostsSet.size() == 0) { 2311 allHostsSet.add("*"); 2312 } 2313 ArrayList<String> allHostsList = new ArrayList<>(allHostsSet); 2314 IntentFilterVerificationInfo ivi = 2315 mSettings.createIntentFilterVerificationIfNeededLPw(packageName, allHostsList); 2316 if (ivi != null) { 2317 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 2318 "Priming domain verifications for package: " + packageName + 2319 " with hosts:" + ivi.getDomainsString()); 2320 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 2321 updated = true; 2322 } 2323 else { 2324 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 2325 "No priming domain verifications for package: " + packageName); 2326 } 2327 allHostsSet.clear(); 2328 } 2329 if (updated) { 2330 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 2331 "Will need to write primed domain verifications"); 2332 } 2333 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "End priming domain verifications"); 2334 } 2335 2336 private void checkDefaultBrowser() { 2337 final int myUserId = UserHandle.myUserId(); 2338 final String packageName = getDefaultBrowserPackageName(myUserId); 2339 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2340 if (info == null) { 2341 Slog.w(TAG, "Clearing default Browser as its package is no more installed: " + 2342 packageName); 2343 setDefaultBrowserPackageName(null, myUserId); 2344 } 2345 } 2346 2347 @Override 2348 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2349 throws RemoteException { 2350 try { 2351 return super.onTransact(code, data, reply, flags); 2352 } catch (RuntimeException e) { 2353 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2354 Slog.wtf(TAG, "Package Manager Crash", e); 2355 } 2356 throw e; 2357 } 2358 } 2359 2360 void cleanupInstallFailedPackage(PackageSetting ps) { 2361 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2362 2363 removeDataDirsLI(ps.volumeUuid, ps.name); 2364 if (ps.codePath != null) { 2365 if (ps.codePath.isDirectory()) { 2366 mInstaller.rmPackageDir(ps.codePath.getAbsolutePath()); 2367 } else { 2368 ps.codePath.delete(); 2369 } 2370 } 2371 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2372 if (ps.resourcePath.isDirectory()) { 2373 FileUtils.deleteContents(ps.resourcePath); 2374 } 2375 ps.resourcePath.delete(); 2376 } 2377 mSettings.removePackageLPw(ps.name); 2378 } 2379 2380 static int[] appendInts(int[] cur, int[] add) { 2381 if (add == null) return cur; 2382 if (cur == null) return add; 2383 final int N = add.length; 2384 for (int i=0; i<N; i++) { 2385 cur = appendInt(cur, add[i]); 2386 } 2387 return cur; 2388 } 2389 2390 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2391 if (!sUserManager.exists(userId)) return null; 2392 final PackageSetting ps = (PackageSetting) p.mExtras; 2393 if (ps == null) { 2394 return null; 2395 } 2396 2397 final PermissionsState permissionsState = ps.getPermissionsState(); 2398 2399 final int[] gids = permissionsState.computeGids(userId); 2400 final Set<String> permissions = permissionsState.getPermissions(userId); 2401 final PackageUserState state = ps.readUserState(userId); 2402 2403 return PackageParser.generatePackageInfo(p, gids, flags, 2404 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2405 } 2406 2407 @Override 2408 public boolean isPackageFrozen(String packageName) { 2409 synchronized (mPackages) { 2410 final PackageSetting ps = mSettings.mPackages.get(packageName); 2411 if (ps != null) { 2412 return ps.frozen; 2413 } 2414 } 2415 Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen"); 2416 return true; 2417 } 2418 2419 @Override 2420 public boolean isPackageAvailable(String packageName, int userId) { 2421 if (!sUserManager.exists(userId)) return false; 2422 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 2423 synchronized (mPackages) { 2424 PackageParser.Package p = mPackages.get(packageName); 2425 if (p != null) { 2426 final PackageSetting ps = (PackageSetting) p.mExtras; 2427 if (ps != null) { 2428 final PackageUserState state = ps.readUserState(userId); 2429 if (state != null) { 2430 return PackageParser.isAvailable(state); 2431 } 2432 } 2433 } 2434 } 2435 return false; 2436 } 2437 2438 @Override 2439 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2440 if (!sUserManager.exists(userId)) return null; 2441 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 2442 // reader 2443 synchronized (mPackages) { 2444 PackageParser.Package p = mPackages.get(packageName); 2445 if (DEBUG_PACKAGE_INFO) 2446 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2447 if (p != null) { 2448 return generatePackageInfo(p, flags, userId); 2449 } 2450 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2451 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2452 } 2453 } 2454 return null; 2455 } 2456 2457 @Override 2458 public String[] currentToCanonicalPackageNames(String[] names) { 2459 String[] out = new String[names.length]; 2460 // reader 2461 synchronized (mPackages) { 2462 for (int i=names.length-1; i>=0; i--) { 2463 PackageSetting ps = mSettings.mPackages.get(names[i]); 2464 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2465 } 2466 } 2467 return out; 2468 } 2469 2470 @Override 2471 public String[] canonicalToCurrentPackageNames(String[] names) { 2472 String[] out = new String[names.length]; 2473 // reader 2474 synchronized (mPackages) { 2475 for (int i=names.length-1; i>=0; i--) { 2476 String cur = mSettings.mRenamedPackages.get(names[i]); 2477 out[i] = cur != null ? cur : names[i]; 2478 } 2479 } 2480 return out; 2481 } 2482 2483 @Override 2484 public int getPackageUid(String packageName, int userId) { 2485 if (!sUserManager.exists(userId)) return -1; 2486 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 2487 2488 // reader 2489 synchronized (mPackages) { 2490 PackageParser.Package p = mPackages.get(packageName); 2491 if(p != null) { 2492 return UserHandle.getUid(userId, p.applicationInfo.uid); 2493 } 2494 PackageSetting ps = mSettings.mPackages.get(packageName); 2495 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 2496 return -1; 2497 } 2498 p = ps.pkg; 2499 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 2500 } 2501 } 2502 2503 @Override 2504 public int[] getPackageGids(String packageName, int userId) throws RemoteException { 2505 if (!sUserManager.exists(userId)) { 2506 return null; 2507 } 2508 2509 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 2510 "getPackageGids"); 2511 2512 // reader 2513 synchronized (mPackages) { 2514 PackageParser.Package p = mPackages.get(packageName); 2515 if (DEBUG_PACKAGE_INFO) { 2516 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 2517 } 2518 if (p != null) { 2519 PackageSetting ps = (PackageSetting) p.mExtras; 2520 return ps.getPermissionsState().computeGids(userId); 2521 } 2522 } 2523 2524 return null; 2525 } 2526 2527 static PermissionInfo generatePermissionInfo( 2528 BasePermission bp, int flags) { 2529 if (bp.perm != null) { 2530 return PackageParser.generatePermissionInfo(bp.perm, flags); 2531 } 2532 PermissionInfo pi = new PermissionInfo(); 2533 pi.name = bp.name; 2534 pi.packageName = bp.sourcePackage; 2535 pi.nonLocalizedLabel = bp.name; 2536 pi.protectionLevel = bp.protectionLevel; 2537 return pi; 2538 } 2539 2540 @Override 2541 public PermissionInfo getPermissionInfo(String name, int flags) { 2542 // reader 2543 synchronized (mPackages) { 2544 final BasePermission p = mSettings.mPermissions.get(name); 2545 if (p != null) { 2546 return generatePermissionInfo(p, flags); 2547 } 2548 return null; 2549 } 2550 } 2551 2552 @Override 2553 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2554 // reader 2555 synchronized (mPackages) { 2556 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2557 for (BasePermission p : mSettings.mPermissions.values()) { 2558 if (group == null) { 2559 if (p.perm == null || p.perm.info.group == null) { 2560 out.add(generatePermissionInfo(p, flags)); 2561 } 2562 } else { 2563 if (p.perm != null && group.equals(p.perm.info.group)) { 2564 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2565 } 2566 } 2567 } 2568 2569 if (out.size() > 0) { 2570 return out; 2571 } 2572 return mPermissionGroups.containsKey(group) ? out : null; 2573 } 2574 } 2575 2576 @Override 2577 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2578 // reader 2579 synchronized (mPackages) { 2580 return PackageParser.generatePermissionGroupInfo( 2581 mPermissionGroups.get(name), flags); 2582 } 2583 } 2584 2585 @Override 2586 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2587 // reader 2588 synchronized (mPackages) { 2589 final int N = mPermissionGroups.size(); 2590 ArrayList<PermissionGroupInfo> out 2591 = new ArrayList<PermissionGroupInfo>(N); 2592 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2593 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2594 } 2595 return out; 2596 } 2597 } 2598 2599 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2600 int userId) { 2601 if (!sUserManager.exists(userId)) return null; 2602 PackageSetting ps = mSettings.mPackages.get(packageName); 2603 if (ps != null) { 2604 if (ps.pkg == null) { 2605 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2606 flags, userId); 2607 if (pInfo != null) { 2608 return pInfo.applicationInfo; 2609 } 2610 return null; 2611 } 2612 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2613 ps.readUserState(userId), userId); 2614 } 2615 return null; 2616 } 2617 2618 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2619 int userId) { 2620 if (!sUserManager.exists(userId)) return null; 2621 PackageSetting ps = mSettings.mPackages.get(packageName); 2622 if (ps != null) { 2623 PackageParser.Package pkg = ps.pkg; 2624 if (pkg == null) { 2625 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2626 return null; 2627 } 2628 // Only data remains, so we aren't worried about code paths 2629 pkg = new PackageParser.Package(packageName); 2630 pkg.applicationInfo.packageName = packageName; 2631 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2632 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 2633 pkg.applicationInfo.dataDir = PackageManager.getDataDirForUser(ps.volumeUuid, 2634 packageName, userId).getAbsolutePath(); 2635 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2636 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2637 } 2638 return generatePackageInfo(pkg, flags, userId); 2639 } 2640 return null; 2641 } 2642 2643 @Override 2644 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2645 if (!sUserManager.exists(userId)) return null; 2646 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2647 // writer 2648 synchronized (mPackages) { 2649 PackageParser.Package p = mPackages.get(packageName); 2650 if (DEBUG_PACKAGE_INFO) Log.v( 2651 TAG, "getApplicationInfo " + packageName 2652 + ": " + p); 2653 if (p != null) { 2654 PackageSetting ps = mSettings.mPackages.get(packageName); 2655 if (ps == null) return null; 2656 // Note: isEnabledLP() does not apply here - always return info 2657 return PackageParser.generateApplicationInfo( 2658 p, flags, ps.readUserState(userId), userId); 2659 } 2660 if ("android".equals(packageName)||"system".equals(packageName)) { 2661 return mAndroidApplication; 2662 } 2663 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2664 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2665 } 2666 } 2667 return null; 2668 } 2669 2670 @Override 2671 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 2672 final IPackageDataObserver observer) { 2673 mContext.enforceCallingOrSelfPermission( 2674 android.Manifest.permission.CLEAR_APP_CACHE, null); 2675 // Queue up an async operation since clearing cache may take a little while. 2676 mHandler.post(new Runnable() { 2677 public void run() { 2678 mHandler.removeCallbacks(this); 2679 int retCode = -1; 2680 synchronized (mInstallLock) { 2681 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2682 if (retCode < 0) { 2683 Slog.w(TAG, "Couldn't clear application caches"); 2684 } 2685 } 2686 if (observer != null) { 2687 try { 2688 observer.onRemoveCompleted(null, (retCode >= 0)); 2689 } catch (RemoteException e) { 2690 Slog.w(TAG, "RemoveException when invoking call back"); 2691 } 2692 } 2693 } 2694 }); 2695 } 2696 2697 @Override 2698 public void freeStorage(final String volumeUuid, final long freeStorageSize, 2699 final IntentSender pi) { 2700 mContext.enforceCallingOrSelfPermission( 2701 android.Manifest.permission.CLEAR_APP_CACHE, null); 2702 // Queue up an async operation since clearing cache may take a little while. 2703 mHandler.post(new Runnable() { 2704 public void run() { 2705 mHandler.removeCallbacks(this); 2706 int retCode = -1; 2707 synchronized (mInstallLock) { 2708 retCode = mInstaller.freeCache(volumeUuid, freeStorageSize); 2709 if (retCode < 0) { 2710 Slog.w(TAG, "Couldn't clear application caches"); 2711 } 2712 } 2713 if(pi != null) { 2714 try { 2715 // Callback via pending intent 2716 int code = (retCode >= 0) ? 1 : 0; 2717 pi.sendIntent(null, code, null, 2718 null, null); 2719 } catch (SendIntentException e1) { 2720 Slog.i(TAG, "Failed to send pending intent"); 2721 } 2722 } 2723 } 2724 }); 2725 } 2726 2727 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 2728 synchronized (mInstallLock) { 2729 if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) { 2730 throw new IOException("Failed to free enough space"); 2731 } 2732 } 2733 } 2734 2735 @Override 2736 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2737 if (!sUserManager.exists(userId)) return null; 2738 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 2739 synchronized (mPackages) { 2740 PackageParser.Activity a = mActivities.mActivities.get(component); 2741 2742 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2743 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2744 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2745 if (ps == null) return null; 2746 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2747 userId); 2748 } 2749 if (mResolveComponentName.equals(component)) { 2750 return PackageParser.generateActivityInfo(mResolveActivity, flags, 2751 new PackageUserState(), userId); 2752 } 2753 } 2754 return null; 2755 } 2756 2757 @Override 2758 public boolean activitySupportsIntent(ComponentName component, Intent intent, 2759 String resolvedType) { 2760 synchronized (mPackages) { 2761 PackageParser.Activity a = mActivities.mActivities.get(component); 2762 if (a == null) { 2763 return false; 2764 } 2765 for (int i=0; i<a.intents.size(); i++) { 2766 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 2767 intent.getData(), intent.getCategories(), TAG) >= 0) { 2768 return true; 2769 } 2770 } 2771 return false; 2772 } 2773 } 2774 2775 @Override 2776 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2777 if (!sUserManager.exists(userId)) return null; 2778 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 2779 synchronized (mPackages) { 2780 PackageParser.Activity a = mReceivers.mActivities.get(component); 2781 if (DEBUG_PACKAGE_INFO) Log.v( 2782 TAG, "getReceiverInfo " + component + ": " + a); 2783 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2784 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2785 if (ps == null) return null; 2786 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2787 userId); 2788 } 2789 } 2790 return null; 2791 } 2792 2793 @Override 2794 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2795 if (!sUserManager.exists(userId)) return null; 2796 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 2797 synchronized (mPackages) { 2798 PackageParser.Service s = mServices.mServices.get(component); 2799 if (DEBUG_PACKAGE_INFO) Log.v( 2800 TAG, "getServiceInfo " + component + ": " + s); 2801 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2802 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2803 if (ps == null) return null; 2804 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2805 userId); 2806 } 2807 } 2808 return null; 2809 } 2810 2811 @Override 2812 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2813 if (!sUserManager.exists(userId)) return null; 2814 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 2815 synchronized (mPackages) { 2816 PackageParser.Provider p = mProviders.mProviders.get(component); 2817 if (DEBUG_PACKAGE_INFO) Log.v( 2818 TAG, "getProviderInfo " + component + ": " + p); 2819 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2820 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2821 if (ps == null) return null; 2822 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2823 userId); 2824 } 2825 } 2826 return null; 2827 } 2828 2829 @Override 2830 public String[] getSystemSharedLibraryNames() { 2831 Set<String> libSet; 2832 synchronized (mPackages) { 2833 libSet = mSharedLibraries.keySet(); 2834 int size = libSet.size(); 2835 if (size > 0) { 2836 String[] libs = new String[size]; 2837 libSet.toArray(libs); 2838 return libs; 2839 } 2840 } 2841 return null; 2842 } 2843 2844 /** 2845 * @hide 2846 */ 2847 PackageParser.Package findSharedNonSystemLibrary(String libName) { 2848 synchronized (mPackages) { 2849 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 2850 if (lib != null && lib.apk != null) { 2851 return mPackages.get(lib.apk); 2852 } 2853 } 2854 return null; 2855 } 2856 2857 @Override 2858 public FeatureInfo[] getSystemAvailableFeatures() { 2859 Collection<FeatureInfo> featSet; 2860 synchronized (mPackages) { 2861 featSet = mAvailableFeatures.values(); 2862 int size = featSet.size(); 2863 if (size > 0) { 2864 FeatureInfo[] features = new FeatureInfo[size+1]; 2865 featSet.toArray(features); 2866 FeatureInfo fi = new FeatureInfo(); 2867 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2868 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2869 features[size] = fi; 2870 return features; 2871 } 2872 } 2873 return null; 2874 } 2875 2876 @Override 2877 public boolean hasSystemFeature(String name) { 2878 synchronized (mPackages) { 2879 return mAvailableFeatures.containsKey(name); 2880 } 2881 } 2882 2883 private void checkValidCaller(int uid, int userId) { 2884 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2885 return; 2886 2887 throw new SecurityException("Caller uid=" + uid 2888 + " is not privileged to communicate with user=" + userId); 2889 } 2890 2891 @Override 2892 public int checkPermission(String permName, String pkgName, int userId) { 2893 if (!sUserManager.exists(userId)) { 2894 return PackageManager.PERMISSION_DENIED; 2895 } 2896 2897 synchronized (mPackages) { 2898 final PackageParser.Package p = mPackages.get(pkgName); 2899 if (p != null && p.mExtras != null) { 2900 final PackageSetting ps = (PackageSetting) p.mExtras; 2901 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2902 return PackageManager.PERMISSION_GRANTED; 2903 } 2904 } 2905 } 2906 2907 return PackageManager.PERMISSION_DENIED; 2908 } 2909 2910 @Override 2911 public int checkUidPermission(String permName, int uid) { 2912 final int userId = UserHandle.getUserId(uid); 2913 2914 if (!sUserManager.exists(userId)) { 2915 return PackageManager.PERMISSION_DENIED; 2916 } 2917 2918 synchronized (mPackages) { 2919 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2920 if (obj != null) { 2921 final SettingBase ps = (SettingBase) obj; 2922 if (ps.getPermissionsState().hasPermission(permName, userId)) { 2923 return PackageManager.PERMISSION_GRANTED; 2924 } 2925 } else { 2926 ArraySet<String> perms = mSystemPermissions.get(uid); 2927 if (perms != null && perms.contains(permName)) { 2928 return PackageManager.PERMISSION_GRANTED; 2929 } 2930 } 2931 } 2932 2933 return PackageManager.PERMISSION_DENIED; 2934 } 2935 2936 /** 2937 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2938 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2939 * @param checkShell TODO(yamasani): 2940 * @param message the message to log on security exception 2941 */ 2942 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 2943 boolean checkShell, String message) { 2944 if (userId < 0) { 2945 throw new IllegalArgumentException("Invalid userId " + userId); 2946 } 2947 if (checkShell) { 2948 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 2949 } 2950 if (userId == UserHandle.getUserId(callingUid)) return; 2951 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2952 if (requireFullPermission) { 2953 mContext.enforceCallingOrSelfPermission( 2954 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2955 } else { 2956 try { 2957 mContext.enforceCallingOrSelfPermission( 2958 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2959 } catch (SecurityException se) { 2960 mContext.enforceCallingOrSelfPermission( 2961 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2962 } 2963 } 2964 } 2965 } 2966 2967 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 2968 if (callingUid == Process.SHELL_UID) { 2969 if (userHandle >= 0 2970 && sUserManager.hasUserRestriction(restriction, userHandle)) { 2971 throw new SecurityException("Shell does not have permission to access user " 2972 + userHandle); 2973 } else if (userHandle < 0) { 2974 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 2975 + Debug.getCallers(3)); 2976 } 2977 } 2978 } 2979 2980 private BasePermission findPermissionTreeLP(String permName) { 2981 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2982 if (permName.startsWith(bp.name) && 2983 permName.length() > bp.name.length() && 2984 permName.charAt(bp.name.length()) == '.') { 2985 return bp; 2986 } 2987 } 2988 return null; 2989 } 2990 2991 private BasePermission checkPermissionTreeLP(String permName) { 2992 if (permName != null) { 2993 BasePermission bp = findPermissionTreeLP(permName); 2994 if (bp != null) { 2995 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2996 return bp; 2997 } 2998 throw new SecurityException("Calling uid " 2999 + Binder.getCallingUid() 3000 + " is not allowed to add to permission tree " 3001 + bp.name + " owned by uid " + bp.uid); 3002 } 3003 } 3004 throw new SecurityException("No permission tree found for " + permName); 3005 } 3006 3007 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3008 if (s1 == null) { 3009 return s2 == null; 3010 } 3011 if (s2 == null) { 3012 return false; 3013 } 3014 if (s1.getClass() != s2.getClass()) { 3015 return false; 3016 } 3017 return s1.equals(s2); 3018 } 3019 3020 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3021 if (pi1.icon != pi2.icon) return false; 3022 if (pi1.logo != pi2.logo) return false; 3023 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3024 if (!compareStrings(pi1.name, pi2.name)) return false; 3025 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3026 // We'll take care of setting this one. 3027 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3028 // These are not currently stored in settings. 3029 //if (!compareStrings(pi1.group, pi2.group)) return false; 3030 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3031 //if (pi1.labelRes != pi2.labelRes) return false; 3032 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3033 return true; 3034 } 3035 3036 int permissionInfoFootprint(PermissionInfo info) { 3037 int size = info.name.length(); 3038 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3039 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3040 return size; 3041 } 3042 3043 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3044 int size = 0; 3045 for (BasePermission perm : mSettings.mPermissions.values()) { 3046 if (perm.uid == tree.uid) { 3047 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3048 } 3049 } 3050 return size; 3051 } 3052 3053 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3054 // We calculate the max size of permissions defined by this uid and throw 3055 // if that plus the size of 'info' would exceed our stated maximum. 3056 if (tree.uid != Process.SYSTEM_UID) { 3057 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3058 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3059 throw new SecurityException("Permission tree size cap exceeded"); 3060 } 3061 } 3062 } 3063 3064 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3065 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3066 throw new SecurityException("Label must be specified in permission"); 3067 } 3068 BasePermission tree = checkPermissionTreeLP(info.name); 3069 BasePermission bp = mSettings.mPermissions.get(info.name); 3070 boolean added = bp == null; 3071 boolean changed = true; 3072 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3073 if (added) { 3074 enforcePermissionCapLocked(info, tree); 3075 bp = new BasePermission(info.name, tree.sourcePackage, 3076 BasePermission.TYPE_DYNAMIC); 3077 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3078 throw new SecurityException( 3079 "Not allowed to modify non-dynamic permission " 3080 + info.name); 3081 } else { 3082 if (bp.protectionLevel == fixedLevel 3083 && bp.perm.owner.equals(tree.perm.owner) 3084 && bp.uid == tree.uid 3085 && comparePermissionInfos(bp.perm.info, info)) { 3086 changed = false; 3087 } 3088 } 3089 bp.protectionLevel = fixedLevel; 3090 info = new PermissionInfo(info); 3091 info.protectionLevel = fixedLevel; 3092 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3093 bp.perm.info.packageName = tree.perm.info.packageName; 3094 bp.uid = tree.uid; 3095 if (added) { 3096 mSettings.mPermissions.put(info.name, bp); 3097 } 3098 if (changed) { 3099 if (!async) { 3100 mSettings.writeLPr(); 3101 } else { 3102 scheduleWriteSettingsLocked(); 3103 } 3104 } 3105 return added; 3106 } 3107 3108 @Override 3109 public boolean addPermission(PermissionInfo info) { 3110 synchronized (mPackages) { 3111 return addPermissionLocked(info, false); 3112 } 3113 } 3114 3115 @Override 3116 public boolean addPermissionAsync(PermissionInfo info) { 3117 synchronized (mPackages) { 3118 return addPermissionLocked(info, true); 3119 } 3120 } 3121 3122 @Override 3123 public void removePermission(String name) { 3124 synchronized (mPackages) { 3125 checkPermissionTreeLP(name); 3126 BasePermission bp = mSettings.mPermissions.get(name); 3127 if (bp != null) { 3128 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3129 throw new SecurityException( 3130 "Not allowed to modify non-dynamic permission " 3131 + name); 3132 } 3133 mSettings.mPermissions.remove(name); 3134 mSettings.writeLPr(); 3135 } 3136 } 3137 } 3138 3139 private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg, 3140 BasePermission bp) { 3141 int index = pkg.requestedPermissions.indexOf(bp.name); 3142 if (index == -1) { 3143 throw new SecurityException("Package " + pkg.packageName 3144 + " has not requested permission " + bp.name); 3145 } 3146 if (!bp.isRuntime()) { 3147 throw new SecurityException("Permission " + bp.name 3148 + " is not a changeable permission type"); 3149 } 3150 } 3151 3152 @Override 3153 public void grantRuntimePermission(String packageName, String name, int userId) { 3154 if (!sUserManager.exists(userId)) { 3155 Log.e(TAG, "No such user:" + userId); 3156 return; 3157 } 3158 3159 mContext.enforceCallingOrSelfPermission( 3160 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3161 "grantRuntimePermission"); 3162 3163 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3164 "grantRuntimePermission"); 3165 3166 boolean gidsChanged = false; 3167 final SettingBase sb; 3168 3169 synchronized (mPackages) { 3170 final PackageParser.Package pkg = mPackages.get(packageName); 3171 if (pkg == null) { 3172 throw new IllegalArgumentException("Unknown package: " + packageName); 3173 } 3174 3175 final BasePermission bp = mSettings.mPermissions.get(name); 3176 if (bp == null) { 3177 throw new IllegalArgumentException("Unknown permission: " + name); 3178 } 3179 3180 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3181 3182 sb = (SettingBase) pkg.mExtras; 3183 if (sb == null) { 3184 throw new IllegalArgumentException("Unknown package: " + packageName); 3185 } 3186 3187 final PermissionsState permissionsState = sb.getPermissionsState(); 3188 3189 final int flags = permissionsState.getPermissionFlags(name, userId); 3190 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3191 throw new SecurityException("Cannot grant system fixed permission: " 3192 + name + " for package: " + packageName); 3193 } 3194 3195 final int result = permissionsState.grantRuntimePermission(bp, userId); 3196 switch (result) { 3197 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3198 return; 3199 } 3200 3201 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3202 gidsChanged = true; 3203 } break; 3204 } 3205 3206 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 3207 3208 // Not critical if that is lost - app has to request again. 3209 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3210 } 3211 3212 if (gidsChanged) { 3213 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED); 3214 } 3215 } 3216 3217 @Override 3218 public void revokeRuntimePermission(String packageName, String name, int userId) { 3219 if (!sUserManager.exists(userId)) { 3220 Log.e(TAG, "No such user:" + userId); 3221 return; 3222 } 3223 3224 mContext.enforceCallingOrSelfPermission( 3225 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3226 "revokeRuntimePermission"); 3227 3228 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3229 "revokeRuntimePermission"); 3230 3231 final SettingBase sb; 3232 3233 synchronized (mPackages) { 3234 final PackageParser.Package pkg = mPackages.get(packageName); 3235 if (pkg == null) { 3236 throw new IllegalArgumentException("Unknown package: " + packageName); 3237 } 3238 3239 final BasePermission bp = mSettings.mPermissions.get(name); 3240 if (bp == null) { 3241 throw new IllegalArgumentException("Unknown permission: " + name); 3242 } 3243 3244 enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); 3245 3246 sb = (SettingBase) pkg.mExtras; 3247 if (sb == null) { 3248 throw new IllegalArgumentException("Unknown package: " + packageName); 3249 } 3250 3251 final PermissionsState permissionsState = sb.getPermissionsState(); 3252 3253 final int flags = permissionsState.getPermissionFlags(name, userId); 3254 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3255 throw new SecurityException("Cannot revoke system fixed permission: " 3256 + name + " for package: " + packageName); 3257 } 3258 3259 if (permissionsState.revokeRuntimePermission(bp, userId) == 3260 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3261 return; 3262 } 3263 3264 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 3265 3266 // Critical, after this call app should never have the permission. 3267 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3268 } 3269 3270 killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 3271 } 3272 3273 @Override 3274 public int getPermissionFlags(String name, String packageName, int userId) { 3275 if (!sUserManager.exists(userId)) { 3276 return 0; 3277 } 3278 3279 mContext.enforceCallingOrSelfPermission( 3280 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3281 "getPermissionFlags"); 3282 3283 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3284 "getPermissionFlags"); 3285 3286 synchronized (mPackages) { 3287 final PackageParser.Package pkg = mPackages.get(packageName); 3288 if (pkg == null) { 3289 throw new IllegalArgumentException("Unknown package: " + packageName); 3290 } 3291 3292 final BasePermission bp = mSettings.mPermissions.get(name); 3293 if (bp == null) { 3294 throw new IllegalArgumentException("Unknown permission: " + name); 3295 } 3296 3297 SettingBase sb = (SettingBase) pkg.mExtras; 3298 if (sb == null) { 3299 throw new IllegalArgumentException("Unknown package: " + packageName); 3300 } 3301 3302 PermissionsState permissionsState = sb.getPermissionsState(); 3303 return permissionsState.getPermissionFlags(name, userId); 3304 } 3305 } 3306 3307 @Override 3308 public void updatePermissionFlags(String name, String packageName, int flagMask, 3309 int flagValues, int userId) { 3310 if (!sUserManager.exists(userId)) { 3311 return; 3312 } 3313 3314 mContext.enforceCallingOrSelfPermission( 3315 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, 3316 "updatePermissionFlags"); 3317 3318 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, 3319 "updatePermissionFlags"); 3320 3321 // Only the system can change policy flags. 3322 if (getCallingUid() != Process.SYSTEM_UID) { 3323 flagMask &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; 3324 flagValues &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; 3325 } 3326 3327 // Only the package manager can change system flags. 3328 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3329 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 3330 3331 synchronized (mPackages) { 3332 final PackageParser.Package pkg = mPackages.get(packageName); 3333 if (pkg == null) { 3334 throw new IllegalArgumentException("Unknown package: " + packageName); 3335 } 3336 3337 final BasePermission bp = mSettings.mPermissions.get(name); 3338 if (bp == null) { 3339 throw new IllegalArgumentException("Unknown permission: " + name); 3340 } 3341 3342 SettingBase sb = (SettingBase) pkg.mExtras; 3343 if (sb == null) { 3344 throw new IllegalArgumentException("Unknown package: " + packageName); 3345 } 3346 3347 PermissionsState permissionsState = sb.getPermissionsState(); 3348 3349 // Only the package manager can change flags for system component permissions. 3350 final int flags = permissionsState.getPermissionFlags(bp.name, userId); 3351 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3352 return; 3353 } 3354 3355 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 3356 // Install and runtime permissions are stored in different places, 3357 // so figure out what permission changed and persist the change. 3358 if (permissionsState.getInstallPermissionState(name) != null) { 3359 scheduleWriteSettingsLocked(); 3360 } else if (permissionsState.getRuntimePermissionState(name, userId) != null) { 3361 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3362 } 3363 } 3364 } 3365 } 3366 3367 @Override 3368 public boolean shouldShowRequestPermissionRationale(String permissionName, 3369 String packageName, int userId) { 3370 if (UserHandle.getCallingUserId() != userId) { 3371 mContext.enforceCallingPermission( 3372 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3373 "canShowRequestPermissionRationale for user " + userId); 3374 } 3375 3376 final int uid = getPackageUid(packageName, userId); 3377 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 3378 return false; 3379 } 3380 3381 if (checkPermission(permissionName, packageName, userId) 3382 == PackageManager.PERMISSION_GRANTED) { 3383 return false; 3384 } 3385 3386 final int flags; 3387 3388 final long identity = Binder.clearCallingIdentity(); 3389 try { 3390 flags = getPermissionFlags(permissionName, 3391 packageName, userId); 3392 } finally { 3393 Binder.restoreCallingIdentity(identity); 3394 } 3395 3396 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 3397 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 3398 | PackageManager.FLAG_PERMISSION_USER_FIXED; 3399 3400 if ((flags & fixedFlags) != 0) { 3401 return false; 3402 } 3403 3404 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 3405 } 3406 3407 @Override 3408 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3409 mContext.enforceCallingOrSelfPermission( 3410 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 3411 "addOnPermissionsChangeListener"); 3412 3413 synchronized (mPackages) { 3414 mOnPermissionChangeListeners.addListenerLocked(listener); 3415 } 3416 } 3417 3418 @Override 3419 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 3420 synchronized (mPackages) { 3421 mOnPermissionChangeListeners.removeListenerLocked(listener); 3422 } 3423 } 3424 3425 @Override 3426 public boolean isProtectedBroadcast(String actionName) { 3427 synchronized (mPackages) { 3428 return mProtectedBroadcasts.contains(actionName); 3429 } 3430 } 3431 3432 @Override 3433 public int checkSignatures(String pkg1, String pkg2) { 3434 synchronized (mPackages) { 3435 final PackageParser.Package p1 = mPackages.get(pkg1); 3436 final PackageParser.Package p2 = mPackages.get(pkg2); 3437 if (p1 == null || p1.mExtras == null 3438 || p2 == null || p2.mExtras == null) { 3439 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3440 } 3441 return compareSignatures(p1.mSignatures, p2.mSignatures); 3442 } 3443 } 3444 3445 @Override 3446 public int checkUidSignatures(int uid1, int uid2) { 3447 // Map to base uids. 3448 uid1 = UserHandle.getAppId(uid1); 3449 uid2 = UserHandle.getAppId(uid2); 3450 // reader 3451 synchronized (mPackages) { 3452 Signature[] s1; 3453 Signature[] s2; 3454 Object obj = mSettings.getUserIdLPr(uid1); 3455 if (obj != null) { 3456 if (obj instanceof SharedUserSetting) { 3457 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 3458 } else if (obj instanceof PackageSetting) { 3459 s1 = ((PackageSetting)obj).signatures.mSignatures; 3460 } else { 3461 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3462 } 3463 } else { 3464 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3465 } 3466 obj = mSettings.getUserIdLPr(uid2); 3467 if (obj != null) { 3468 if (obj instanceof SharedUserSetting) { 3469 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 3470 } else if (obj instanceof PackageSetting) { 3471 s2 = ((PackageSetting)obj).signatures.mSignatures; 3472 } else { 3473 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3474 } 3475 } else { 3476 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 3477 } 3478 return compareSignatures(s1, s2); 3479 } 3480 } 3481 3482 private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) { 3483 final long identity = Binder.clearCallingIdentity(); 3484 try { 3485 if (sb instanceof SharedUserSetting) { 3486 SharedUserSetting sus = (SharedUserSetting) sb; 3487 final int packageCount = sus.packages.size(); 3488 for (int i = 0; i < packageCount; i++) { 3489 PackageSetting susPs = sus.packages.valueAt(i); 3490 if (userId == UserHandle.USER_ALL) { 3491 killApplication(susPs.pkg.packageName, susPs.appId, reason); 3492 } else { 3493 final int uid = UserHandle.getUid(userId, susPs.appId); 3494 killUid(uid, reason); 3495 } 3496 } 3497 } else if (sb instanceof PackageSetting) { 3498 PackageSetting ps = (PackageSetting) sb; 3499 if (userId == UserHandle.USER_ALL) { 3500 killApplication(ps.pkg.packageName, ps.appId, reason); 3501 } else { 3502 final int uid = UserHandle.getUid(userId, ps.appId); 3503 killUid(uid, reason); 3504 } 3505 } 3506 } finally { 3507 Binder.restoreCallingIdentity(identity); 3508 } 3509 } 3510 3511 private static void killUid(int uid, String reason) { 3512 IActivityManager am = ActivityManagerNative.getDefault(); 3513 if (am != null) { 3514 try { 3515 am.killUid(uid, reason); 3516 } catch (RemoteException e) { 3517 /* ignore - same process */ 3518 } 3519 } 3520 } 3521 3522 /** 3523 * Compares two sets of signatures. Returns: 3524 * <br /> 3525 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 3526 * <br /> 3527 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 3528 * <br /> 3529 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 3530 * <br /> 3531 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 3532 * <br /> 3533 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 3534 */ 3535 static int compareSignatures(Signature[] s1, Signature[] s2) { 3536 if (s1 == null) { 3537 return s2 == null 3538 ? PackageManager.SIGNATURE_NEITHER_SIGNED 3539 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 3540 } 3541 3542 if (s2 == null) { 3543 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 3544 } 3545 3546 if (s1.length != s2.length) { 3547 return PackageManager.SIGNATURE_NO_MATCH; 3548 } 3549 3550 // Since both signature sets are of size 1, we can compare without HashSets. 3551 if (s1.length == 1) { 3552 return s1[0].equals(s2[0]) ? 3553 PackageManager.SIGNATURE_MATCH : 3554 PackageManager.SIGNATURE_NO_MATCH; 3555 } 3556 3557 ArraySet<Signature> set1 = new ArraySet<Signature>(); 3558 for (Signature sig : s1) { 3559 set1.add(sig); 3560 } 3561 ArraySet<Signature> set2 = new ArraySet<Signature>(); 3562 for (Signature sig : s2) { 3563 set2.add(sig); 3564 } 3565 // Make sure s2 contains all signatures in s1. 3566 if (set1.equals(set2)) { 3567 return PackageManager.SIGNATURE_MATCH; 3568 } 3569 return PackageManager.SIGNATURE_NO_MATCH; 3570 } 3571 3572 /** 3573 * If the database version for this type of package (internal storage or 3574 * external storage) is less than the version where package signatures 3575 * were updated, return true. 3576 */ 3577 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3578 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan( 3579 DatabaseVersion.SIGNATURE_END_ENTITY)) 3580 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan( 3581 DatabaseVersion.SIGNATURE_END_ENTITY)); 3582 } 3583 3584 /** 3585 * Used for backward compatibility to make sure any packages with 3586 * certificate chains get upgraded to the new style. {@code existingSigs} 3587 * will be in the old format (since they were stored on disk from before the 3588 * system upgrade) and {@code scannedSigs} will be in the newer format. 3589 */ 3590 private int compareSignaturesCompat(PackageSignatures existingSigs, 3591 PackageParser.Package scannedPkg) { 3592 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 3593 return PackageManager.SIGNATURE_NO_MATCH; 3594 } 3595 3596 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 3597 for (Signature sig : existingSigs.mSignatures) { 3598 existingSet.add(sig); 3599 } 3600 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 3601 for (Signature sig : scannedPkg.mSignatures) { 3602 try { 3603 Signature[] chainSignatures = sig.getChainSignatures(); 3604 for (Signature chainSig : chainSignatures) { 3605 scannedCompatSet.add(chainSig); 3606 } 3607 } catch (CertificateEncodingException e) { 3608 scannedCompatSet.add(sig); 3609 } 3610 } 3611 /* 3612 * Make sure the expanded scanned set contains all signatures in the 3613 * existing one. 3614 */ 3615 if (scannedCompatSet.equals(existingSet)) { 3616 // Migrate the old signatures to the new scheme. 3617 existingSigs.assignSignatures(scannedPkg.mSignatures); 3618 // The new KeySets will be re-added later in the scanning process. 3619 synchronized (mPackages) { 3620 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 3621 } 3622 return PackageManager.SIGNATURE_MATCH; 3623 } 3624 return PackageManager.SIGNATURE_NO_MATCH; 3625 } 3626 3627 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 3628 if (isExternal(scannedPkg)) { 3629 return mSettings.isExternalDatabaseVersionOlderThan( 3630 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3631 } else { 3632 return mSettings.isInternalDatabaseVersionOlderThan( 3633 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 3634 } 3635 } 3636 3637 private int compareSignaturesRecover(PackageSignatures existingSigs, 3638 PackageParser.Package scannedPkg) { 3639 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 3640 return PackageManager.SIGNATURE_NO_MATCH; 3641 } 3642 3643 String msg = null; 3644 try { 3645 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 3646 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 3647 + scannedPkg.packageName); 3648 return PackageManager.SIGNATURE_MATCH; 3649 } 3650 } catch (CertificateException e) { 3651 msg = e.getMessage(); 3652 } 3653 3654 logCriticalInfo(Log.INFO, 3655 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 3656 return PackageManager.SIGNATURE_NO_MATCH; 3657 } 3658 3659 @Override 3660 public String[] getPackagesForUid(int uid) { 3661 uid = UserHandle.getAppId(uid); 3662 // reader 3663 synchronized (mPackages) { 3664 Object obj = mSettings.getUserIdLPr(uid); 3665 if (obj instanceof SharedUserSetting) { 3666 final SharedUserSetting sus = (SharedUserSetting) obj; 3667 final int N = sus.packages.size(); 3668 final String[] res = new String[N]; 3669 final Iterator<PackageSetting> it = sus.packages.iterator(); 3670 int i = 0; 3671 while (it.hasNext()) { 3672 res[i++] = it.next().name; 3673 } 3674 return res; 3675 } else if (obj instanceof PackageSetting) { 3676 final PackageSetting ps = (PackageSetting) obj; 3677 return new String[] { ps.name }; 3678 } 3679 } 3680 return null; 3681 } 3682 3683 @Override 3684 public String getNameForUid(int uid) { 3685 // reader 3686 synchronized (mPackages) { 3687 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3688 if (obj instanceof SharedUserSetting) { 3689 final SharedUserSetting sus = (SharedUserSetting) obj; 3690 return sus.name + ":" + sus.userId; 3691 } else if (obj instanceof PackageSetting) { 3692 final PackageSetting ps = (PackageSetting) obj; 3693 return ps.name; 3694 } 3695 } 3696 return null; 3697 } 3698 3699 @Override 3700 public int getUidForSharedUser(String sharedUserName) { 3701 if(sharedUserName == null) { 3702 return -1; 3703 } 3704 // reader 3705 synchronized (mPackages) { 3706 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 3707 if (suid == null) { 3708 return -1; 3709 } 3710 return suid.userId; 3711 } 3712 } 3713 3714 @Override 3715 public int getFlagsForUid(int uid) { 3716 synchronized (mPackages) { 3717 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3718 if (obj instanceof SharedUserSetting) { 3719 final SharedUserSetting sus = (SharedUserSetting) obj; 3720 return sus.pkgFlags; 3721 } else if (obj instanceof PackageSetting) { 3722 final PackageSetting ps = (PackageSetting) obj; 3723 return ps.pkgFlags; 3724 } 3725 } 3726 return 0; 3727 } 3728 3729 @Override 3730 public int getPrivateFlagsForUid(int uid) { 3731 synchronized (mPackages) { 3732 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3733 if (obj instanceof SharedUserSetting) { 3734 final SharedUserSetting sus = (SharedUserSetting) obj; 3735 return sus.pkgPrivateFlags; 3736 } else if (obj instanceof PackageSetting) { 3737 final PackageSetting ps = (PackageSetting) obj; 3738 return ps.pkgPrivateFlags; 3739 } 3740 } 3741 return 0; 3742 } 3743 3744 @Override 3745 public boolean isUidPrivileged(int uid) { 3746 uid = UserHandle.getAppId(uid); 3747 // reader 3748 synchronized (mPackages) { 3749 Object obj = mSettings.getUserIdLPr(uid); 3750 if (obj instanceof SharedUserSetting) { 3751 final SharedUserSetting sus = (SharedUserSetting) obj; 3752 final Iterator<PackageSetting> it = sus.packages.iterator(); 3753 while (it.hasNext()) { 3754 if (it.next().isPrivileged()) { 3755 return true; 3756 } 3757 } 3758 } else if (obj instanceof PackageSetting) { 3759 final PackageSetting ps = (PackageSetting) obj; 3760 return ps.isPrivileged(); 3761 } 3762 } 3763 return false; 3764 } 3765 3766 @Override 3767 public String[] getAppOpPermissionPackages(String permissionName) { 3768 synchronized (mPackages) { 3769 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 3770 if (pkgs == null) { 3771 return null; 3772 } 3773 return pkgs.toArray(new String[pkgs.size()]); 3774 } 3775 } 3776 3777 @Override 3778 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 3779 int flags, int userId) { 3780 if (!sUserManager.exists(userId)) return null; 3781 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 3782 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3783 return chooseBestActivity(intent, resolvedType, flags, query, userId); 3784 } 3785 3786 @Override 3787 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 3788 IntentFilter filter, int match, ComponentName activity) { 3789 final int userId = UserHandle.getCallingUserId(); 3790 if (DEBUG_PREFERRED) { 3791 Log.v(TAG, "setLastChosenActivity intent=" + intent 3792 + " resolvedType=" + resolvedType 3793 + " flags=" + flags 3794 + " filter=" + filter 3795 + " match=" + match 3796 + " activity=" + activity); 3797 filter.dump(new PrintStreamPrinter(System.out), " "); 3798 } 3799 intent.setComponent(null); 3800 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3801 // Find any earlier preferred or last chosen entries and nuke them 3802 findPreferredActivity(intent, resolvedType, 3803 flags, query, 0, false, true, false, userId); 3804 // Add the new activity as the last chosen for this filter 3805 addPreferredActivityInternal(filter, match, null, activity, false, userId, 3806 "Setting last chosen"); 3807 } 3808 3809 @Override 3810 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 3811 final int userId = UserHandle.getCallingUserId(); 3812 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 3813 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3814 return findPreferredActivity(intent, resolvedType, flags, query, 0, 3815 false, false, false, userId); 3816 } 3817 3818 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 3819 int flags, List<ResolveInfo> query, int userId) { 3820 if (query != null) { 3821 final int N = query.size(); 3822 if (N == 1) { 3823 return query.get(0); 3824 } else if (N > 1) { 3825 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3826 // If there is more than one activity with the same priority, 3827 // then let the user decide between them. 3828 ResolveInfo r0 = query.get(0); 3829 ResolveInfo r1 = query.get(1); 3830 if (DEBUG_INTENT_MATCHING || debug) { 3831 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 3832 + r1.activityInfo.name + "=" + r1.priority); 3833 } 3834 // If the first activity has a higher priority, or a different 3835 // default, then it is always desireable to pick it. 3836 if (r0.priority != r1.priority 3837 || r0.preferredOrder != r1.preferredOrder 3838 || r0.isDefault != r1.isDefault) { 3839 return query.get(0); 3840 } 3841 // If we have saved a preference for a preferred activity for 3842 // this Intent, use that. 3843 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 3844 flags, query, r0.priority, true, false, debug, userId); 3845 if (ri != null) { 3846 return ri; 3847 } 3848 if (userId != 0) { 3849 ri = new ResolveInfo(mResolveInfo); 3850 ri.activityInfo = new ActivityInfo(ri.activityInfo); 3851 ri.activityInfo.applicationInfo = new ApplicationInfo( 3852 ri.activityInfo.applicationInfo); 3853 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 3854 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 3855 return ri; 3856 } 3857 return mResolveInfo; 3858 } 3859 } 3860 return null; 3861 } 3862 3863 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 3864 int flags, List<ResolveInfo> query, boolean debug, int userId) { 3865 final int N = query.size(); 3866 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 3867 .get(userId); 3868 // Get the list of persistent preferred activities that handle the intent 3869 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 3870 List<PersistentPreferredActivity> pprefs = ppir != null 3871 ? ppir.queryIntent(intent, resolvedType, 3872 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3873 : null; 3874 if (pprefs != null && pprefs.size() > 0) { 3875 final int M = pprefs.size(); 3876 for (int i=0; i<M; i++) { 3877 final PersistentPreferredActivity ppa = pprefs.get(i); 3878 if (DEBUG_PREFERRED || debug) { 3879 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 3880 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 3881 + "\n component=" + ppa.mComponent); 3882 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3883 } 3884 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 3885 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3886 if (DEBUG_PREFERRED || debug) { 3887 Slog.v(TAG, "Found persistent preferred activity:"); 3888 if (ai != null) { 3889 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3890 } else { 3891 Slog.v(TAG, " null"); 3892 } 3893 } 3894 if (ai == null) { 3895 // This previously registered persistent preferred activity 3896 // component is no longer known. Ignore it and do NOT remove it. 3897 continue; 3898 } 3899 for (int j=0; j<N; j++) { 3900 final ResolveInfo ri = query.get(j); 3901 if (!ri.activityInfo.applicationInfo.packageName 3902 .equals(ai.applicationInfo.packageName)) { 3903 continue; 3904 } 3905 if (!ri.activityInfo.name.equals(ai.name)) { 3906 continue; 3907 } 3908 // Found a persistent preference that can handle the intent. 3909 if (DEBUG_PREFERRED || debug) { 3910 Slog.v(TAG, "Returning persistent preferred activity: " + 3911 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3912 } 3913 return ri; 3914 } 3915 } 3916 } 3917 return null; 3918 } 3919 3920 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 3921 List<ResolveInfo> query, int priority, boolean always, 3922 boolean removeMatches, boolean debug, int userId) { 3923 if (!sUserManager.exists(userId)) return null; 3924 // writer 3925 synchronized (mPackages) { 3926 if (intent.getSelector() != null) { 3927 intent = intent.getSelector(); 3928 } 3929 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3930 3931 // Try to find a matching persistent preferred activity. 3932 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 3933 debug, userId); 3934 3935 // If a persistent preferred activity matched, use it. 3936 if (pri != null) { 3937 return pri; 3938 } 3939 3940 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 3941 // Get the list of preferred activities that handle the intent 3942 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 3943 List<PreferredActivity> prefs = pir != null 3944 ? pir.queryIntent(intent, resolvedType, 3945 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3946 : null; 3947 if (prefs != null && prefs.size() > 0) { 3948 boolean changed = false; 3949 try { 3950 // First figure out how good the original match set is. 3951 // We will only allow preferred activities that came 3952 // from the same match quality. 3953 int match = 0; 3954 3955 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 3956 3957 final int N = query.size(); 3958 for (int j=0; j<N; j++) { 3959 final ResolveInfo ri = query.get(j); 3960 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 3961 + ": 0x" + Integer.toHexString(match)); 3962 if (ri.match > match) { 3963 match = ri.match; 3964 } 3965 } 3966 3967 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 3968 + Integer.toHexString(match)); 3969 3970 match &= IntentFilter.MATCH_CATEGORY_MASK; 3971 final int M = prefs.size(); 3972 for (int i=0; i<M; i++) { 3973 final PreferredActivity pa = prefs.get(i); 3974 if (DEBUG_PREFERRED || debug) { 3975 Slog.v(TAG, "Checking PreferredActivity ds=" 3976 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 3977 + "\n component=" + pa.mPref.mComponent); 3978 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3979 } 3980 if (pa.mPref.mMatch != match) { 3981 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 3982 + Integer.toHexString(pa.mPref.mMatch)); 3983 continue; 3984 } 3985 // If it's not an "always" type preferred activity and that's what we're 3986 // looking for, skip it. 3987 if (always && !pa.mPref.mAlways) { 3988 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 3989 continue; 3990 } 3991 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 3992 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3993 if (DEBUG_PREFERRED || debug) { 3994 Slog.v(TAG, "Found preferred activity:"); 3995 if (ai != null) { 3996 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3997 } else { 3998 Slog.v(TAG, " null"); 3999 } 4000 } 4001 if (ai == null) { 4002 // This previously registered preferred activity 4003 // component is no longer known. Most likely an update 4004 // to the app was installed and in the new version this 4005 // component no longer exists. Clean it up by removing 4006 // it from the preferred activities list, and skip it. 4007 Slog.w(TAG, "Removing dangling preferred activity: " 4008 + pa.mPref.mComponent); 4009 pir.removeFilter(pa); 4010 changed = true; 4011 continue; 4012 } 4013 for (int j=0; j<N; j++) { 4014 final ResolveInfo ri = query.get(j); 4015 if (!ri.activityInfo.applicationInfo.packageName 4016 .equals(ai.applicationInfo.packageName)) { 4017 continue; 4018 } 4019 if (!ri.activityInfo.name.equals(ai.name)) { 4020 continue; 4021 } 4022 4023 if (removeMatches) { 4024 pir.removeFilter(pa); 4025 changed = true; 4026 if (DEBUG_PREFERRED) { 4027 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4028 } 4029 break; 4030 } 4031 4032 // Okay we found a previously set preferred or last chosen app. 4033 // If the result set is different from when this 4034 // was created, we need to clear it and re-ask the 4035 // user their preference, if we're looking for an "always" type entry. 4036 if (always && !pa.mPref.sameSet(query)) { 4037 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4038 + intent + " type " + resolvedType); 4039 if (DEBUG_PREFERRED) { 4040 Slog.v(TAG, "Removing preferred activity since set changed " 4041 + pa.mPref.mComponent); 4042 } 4043 pir.removeFilter(pa); 4044 // Re-add the filter as a "last chosen" entry (!always) 4045 PreferredActivity lastChosen = new PreferredActivity( 4046 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4047 pir.addFilter(lastChosen); 4048 changed = true; 4049 return null; 4050 } 4051 4052 // Yay! Either the set matched or we're looking for the last chosen 4053 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4054 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4055 return ri; 4056 } 4057 } 4058 } finally { 4059 if (changed) { 4060 if (DEBUG_PREFERRED) { 4061 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 4062 } 4063 scheduleWritePackageRestrictionsLocked(userId); 4064 } 4065 } 4066 } 4067 } 4068 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 4069 return null; 4070 } 4071 4072 /* 4073 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 4074 */ 4075 @Override 4076 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 4077 int targetUserId) { 4078 mContext.enforceCallingOrSelfPermission( 4079 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 4080 List<CrossProfileIntentFilter> matches = 4081 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 4082 if (matches != null) { 4083 int size = matches.size(); 4084 for (int i = 0; i < size; i++) { 4085 if (matches.get(i).getTargetUserId() == targetUserId) return true; 4086 } 4087 } 4088 return false; 4089 } 4090 4091 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 4092 String resolvedType, int userId) { 4093 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 4094 if (resolver != null) { 4095 return resolver.queryIntent(intent, resolvedType, false, userId); 4096 } 4097 return null; 4098 } 4099 4100 @Override 4101 public List<ResolveInfo> queryIntentActivities(Intent intent, 4102 String resolvedType, int flags, int userId) { 4103 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4104 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 4105 ComponentName comp = intent.getComponent(); 4106 if (comp == null) { 4107 if (intent.getSelector() != null) { 4108 intent = intent.getSelector(); 4109 comp = intent.getComponent(); 4110 } 4111 } 4112 4113 if (comp != null) { 4114 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4115 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 4116 if (ai != null) { 4117 final ResolveInfo ri = new ResolveInfo(); 4118 ri.activityInfo = ai; 4119 list.add(ri); 4120 } 4121 return list; 4122 } 4123 4124 // reader 4125 synchronized (mPackages) { 4126 final String pkgName = intent.getPackage(); 4127 if (pkgName == null) { 4128 List<CrossProfileIntentFilter> matchingFilters = 4129 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 4130 // Check for results that need to skip the current profile. 4131 ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 4132 resolvedType, flags, userId); 4133 if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { 4134 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 4135 result.add(resolveInfo); 4136 return filterIfNotPrimaryUser(result, userId); 4137 } 4138 4139 // Check for results in the current profile. 4140 List<ResolveInfo> result = mActivities.queryIntent( 4141 intent, resolvedType, flags, userId); 4142 4143 // Check for cross profile results. 4144 resolveInfo = queryCrossProfileIntents( 4145 matchingFilters, intent, resolvedType, flags, userId); 4146 if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { 4147 result.add(resolveInfo); 4148 Collections.sort(result, mResolvePrioritySorter); 4149 } 4150 result = filterIfNotPrimaryUser(result, userId); 4151 if (result.size() > 1 && hasWebURI(intent)) { 4152 return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result); 4153 } 4154 return result; 4155 } 4156 final PackageParser.Package pkg = mPackages.get(pkgName); 4157 if (pkg != null) { 4158 return filterIfNotPrimaryUser( 4159 mActivities.queryIntentForPackage( 4160 intent, resolvedType, flags, pkg.activities, userId), 4161 userId); 4162 } 4163 return new ArrayList<ResolveInfo>(); 4164 } 4165 } 4166 4167 private boolean isUserEnabled(int userId) { 4168 long callingId = Binder.clearCallingIdentity(); 4169 try { 4170 UserInfo userInfo = sUserManager.getUserInfo(userId); 4171 return userInfo != null && userInfo.isEnabled(); 4172 } finally { 4173 Binder.restoreCallingIdentity(callingId); 4174 } 4175 } 4176 4177 /** 4178 * Filter out activities with primaryUserOnly flag set, when current user is not the owner. 4179 * 4180 * @return filtered list 4181 */ 4182 private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) { 4183 if (userId == UserHandle.USER_OWNER) { 4184 return resolveInfos; 4185 } 4186 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 4187 ResolveInfo info = resolveInfos.get(i); 4188 if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 4189 resolveInfos.remove(i); 4190 } 4191 } 4192 return resolveInfos; 4193 } 4194 4195 private static boolean hasWebURI(Intent intent) { 4196 if (intent.getData() == null) { 4197 return false; 4198 } 4199 final String scheme = intent.getScheme(); 4200 if (TextUtils.isEmpty(scheme)) { 4201 return false; 4202 } 4203 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 4204 } 4205 4206 private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr( 4207 int flags, List<ResolveInfo> candidates) { 4208 if (DEBUG_PREFERRED) { 4209 Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " + 4210 candidates.size()); 4211 } 4212 4213 final int userId = UserHandle.getCallingUserId(); 4214 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 4215 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 4216 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 4217 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 4218 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 4219 4220 synchronized (mPackages) { 4221 final int count = candidates.size(); 4222 // First, try to use the domain prefered App. Partition the candidates into four lists: 4223 // one for the final results, one for the "do not use ever", one for "undefined status" 4224 // and finally one for "Browser App type". 4225 for (int n=0; n<count; n++) { 4226 ResolveInfo info = candidates.get(n); 4227 String packageName = info.activityInfo.packageName; 4228 PackageSetting ps = mSettings.mPackages.get(packageName); 4229 if (ps != null) { 4230 // Add to the special match all list (Browser use case) 4231 if (info.handleAllWebDataURI) { 4232 matchAllList.add(info); 4233 continue; 4234 } 4235 // Try to get the status from User settings first 4236 int status = getDomainVerificationStatusLPr(ps, userId); 4237 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 4238 alwaysList.add(info); 4239 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 4240 neverList.add(info); 4241 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 4242 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 4243 undefinedList.add(info); 4244 } 4245 } 4246 } 4247 // First try to add the "always" if there is any 4248 if (alwaysList.size() > 0) { 4249 result.addAll(alwaysList); 4250 } else { 4251 // Add all undefined Apps as we want them to appear in the Disambiguation dialog. 4252 result.addAll(undefinedList); 4253 // Also add Browsers (all of them or only the default one) 4254 if ((flags & MATCH_ALL) != 0) { 4255 result.addAll(matchAllList); 4256 } else { 4257 // Try to add the Default Browser if we can 4258 final String defaultBrowserPackageName = getDefaultBrowserPackageName( 4259 UserHandle.myUserId()); 4260 if (!TextUtils.isEmpty(defaultBrowserPackageName)) { 4261 boolean defaultBrowserFound = false; 4262 final int browserCount = matchAllList.size(); 4263 for (int n=0; n<browserCount; n++) { 4264 ResolveInfo browser = matchAllList.get(n); 4265 if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) { 4266 result.add(browser); 4267 defaultBrowserFound = true; 4268 break; 4269 } 4270 } 4271 if (!defaultBrowserFound) { 4272 result.addAll(matchAllList); 4273 } 4274 } else { 4275 result.addAll(matchAllList); 4276 } 4277 } 4278 4279 // If there is nothing selected, add all candidates and remove the ones that the User 4280 // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 4281 if (result.size() == 0) { 4282 result.addAll(candidates); 4283 result.removeAll(neverList); 4284 } 4285 } 4286 } 4287 if (DEBUG_PREFERRED) { 4288 Slog.v("TAG", "Filtered results with prefered activities. New candidates count: " + 4289 result.size()); 4290 } 4291 return result; 4292 } 4293 4294 private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 4295 int status = ps.getDomainVerificationStatusForUser(userId); 4296 // if none available, get the master status 4297 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 4298 if (ps.getIntentFilterVerificationInfo() != null) { 4299 status = ps.getIntentFilterVerificationInfo().getStatus(); 4300 } 4301 } 4302 return status; 4303 } 4304 4305 private ResolveInfo querySkipCurrentProfileIntents( 4306 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4307 int flags, int sourceUserId) { 4308 if (matchingFilters != null) { 4309 int size = matchingFilters.size(); 4310 for (int i = 0; i < size; i ++) { 4311 CrossProfileIntentFilter filter = matchingFilters.get(i); 4312 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 4313 // Checking if there are activities in the target user that can handle the 4314 // intent. 4315 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4316 flags, sourceUserId); 4317 if (resolveInfo != null) { 4318 return resolveInfo; 4319 } 4320 } 4321 } 4322 } 4323 return null; 4324 } 4325 4326 // Return matching ResolveInfo if any for skip current profile intent filters. 4327 private ResolveInfo queryCrossProfileIntents( 4328 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 4329 int flags, int sourceUserId) { 4330 if (matchingFilters != null) { 4331 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 4332 // match the same intent. For performance reasons, it is better not to 4333 // run queryIntent twice for the same userId 4334 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 4335 int size = matchingFilters.size(); 4336 for (int i = 0; i < size; i++) { 4337 CrossProfileIntentFilter filter = matchingFilters.get(i); 4338 int targetUserId = filter.getTargetUserId(); 4339 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 4340 && !alreadyTriedUserIds.get(targetUserId)) { 4341 // Checking if there are activities in the target user that can handle the 4342 // intent. 4343 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 4344 flags, sourceUserId); 4345 if (resolveInfo != null) return resolveInfo; 4346 alreadyTriedUserIds.put(targetUserId, true); 4347 } 4348 } 4349 } 4350 return null; 4351 } 4352 4353 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 4354 String resolvedType, int flags, int sourceUserId) { 4355 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 4356 resolvedType, flags, filter.getTargetUserId()); 4357 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 4358 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 4359 } 4360 return null; 4361 } 4362 4363 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 4364 int sourceUserId, int targetUserId) { 4365 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 4366 String className; 4367 if (targetUserId == UserHandle.USER_OWNER) { 4368 className = FORWARD_INTENT_TO_USER_OWNER; 4369 } else { 4370 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 4371 } 4372 ComponentName forwardingActivityComponentName = new ComponentName( 4373 mAndroidApplication.packageName, className); 4374 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 4375 sourceUserId); 4376 if (targetUserId == UserHandle.USER_OWNER) { 4377 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 4378 forwardingResolveInfo.noResourceId = true; 4379 } 4380 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 4381 forwardingResolveInfo.priority = 0; 4382 forwardingResolveInfo.preferredOrder = 0; 4383 forwardingResolveInfo.match = 0; 4384 forwardingResolveInfo.isDefault = true; 4385 forwardingResolveInfo.filter = filter; 4386 forwardingResolveInfo.targetUserId = targetUserId; 4387 return forwardingResolveInfo; 4388 } 4389 4390 @Override 4391 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 4392 Intent[] specifics, String[] specificTypes, Intent intent, 4393 String resolvedType, int flags, int userId) { 4394 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4395 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 4396 false, "query intent activity options"); 4397 final String resultsAction = intent.getAction(); 4398 4399 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 4400 | PackageManager.GET_RESOLVED_FILTER, userId); 4401 4402 if (DEBUG_INTENT_MATCHING) { 4403 Log.v(TAG, "Query " + intent + ": " + results); 4404 } 4405 4406 int specificsPos = 0; 4407 int N; 4408 4409 // todo: note that the algorithm used here is O(N^2). This 4410 // isn't a problem in our current environment, but if we start running 4411 // into situations where we have more than 5 or 10 matches then this 4412 // should probably be changed to something smarter... 4413 4414 // First we go through and resolve each of the specific items 4415 // that were supplied, taking care of removing any corresponding 4416 // duplicate items in the generic resolve list. 4417 if (specifics != null) { 4418 for (int i=0; i<specifics.length; i++) { 4419 final Intent sintent = specifics[i]; 4420 if (sintent == null) { 4421 continue; 4422 } 4423 4424 if (DEBUG_INTENT_MATCHING) { 4425 Log.v(TAG, "Specific #" + i + ": " + sintent); 4426 } 4427 4428 String action = sintent.getAction(); 4429 if (resultsAction != null && resultsAction.equals(action)) { 4430 // If this action was explicitly requested, then don't 4431 // remove things that have it. 4432 action = null; 4433 } 4434 4435 ResolveInfo ri = null; 4436 ActivityInfo ai = null; 4437 4438 ComponentName comp = sintent.getComponent(); 4439 if (comp == null) { 4440 ri = resolveIntent( 4441 sintent, 4442 specificTypes != null ? specificTypes[i] : null, 4443 flags, userId); 4444 if (ri == null) { 4445 continue; 4446 } 4447 if (ri == mResolveInfo) { 4448 // ACK! Must do something better with this. 4449 } 4450 ai = ri.activityInfo; 4451 comp = new ComponentName(ai.applicationInfo.packageName, 4452 ai.name); 4453 } else { 4454 ai = getActivityInfo(comp, flags, userId); 4455 if (ai == null) { 4456 continue; 4457 } 4458 } 4459 4460 // Look for any generic query activities that are duplicates 4461 // of this specific one, and remove them from the results. 4462 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 4463 N = results.size(); 4464 int j; 4465 for (j=specificsPos; j<N; j++) { 4466 ResolveInfo sri = results.get(j); 4467 if ((sri.activityInfo.name.equals(comp.getClassName()) 4468 && sri.activityInfo.applicationInfo.packageName.equals( 4469 comp.getPackageName())) 4470 || (action != null && sri.filter.matchAction(action))) { 4471 results.remove(j); 4472 if (DEBUG_INTENT_MATCHING) Log.v( 4473 TAG, "Removing duplicate item from " + j 4474 + " due to specific " + specificsPos); 4475 if (ri == null) { 4476 ri = sri; 4477 } 4478 j--; 4479 N--; 4480 } 4481 } 4482 4483 // Add this specific item to its proper place. 4484 if (ri == null) { 4485 ri = new ResolveInfo(); 4486 ri.activityInfo = ai; 4487 } 4488 results.add(specificsPos, ri); 4489 ri.specificIndex = i; 4490 specificsPos++; 4491 } 4492 } 4493 4494 // Now we go through the remaining generic results and remove any 4495 // duplicate actions that are found here. 4496 N = results.size(); 4497 for (int i=specificsPos; i<N-1; i++) { 4498 final ResolveInfo rii = results.get(i); 4499 if (rii.filter == null) { 4500 continue; 4501 } 4502 4503 // Iterate over all of the actions of this result's intent 4504 // filter... typically this should be just one. 4505 final Iterator<String> it = rii.filter.actionsIterator(); 4506 if (it == null) { 4507 continue; 4508 } 4509 while (it.hasNext()) { 4510 final String action = it.next(); 4511 if (resultsAction != null && resultsAction.equals(action)) { 4512 // If this action was explicitly requested, then don't 4513 // remove things that have it. 4514 continue; 4515 } 4516 for (int j=i+1; j<N; j++) { 4517 final ResolveInfo rij = results.get(j); 4518 if (rij.filter != null && rij.filter.hasAction(action)) { 4519 results.remove(j); 4520 if (DEBUG_INTENT_MATCHING) Log.v( 4521 TAG, "Removing duplicate item from " + j 4522 + " due to action " + action + " at " + i); 4523 j--; 4524 N--; 4525 } 4526 } 4527 } 4528 4529 // If the caller didn't request filter information, drop it now 4530 // so we don't have to marshall/unmarshall it. 4531 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4532 rii.filter = null; 4533 } 4534 } 4535 4536 // Filter out the caller activity if so requested. 4537 if (caller != null) { 4538 N = results.size(); 4539 for (int i=0; i<N; i++) { 4540 ActivityInfo ainfo = results.get(i).activityInfo; 4541 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 4542 && caller.getClassName().equals(ainfo.name)) { 4543 results.remove(i); 4544 break; 4545 } 4546 } 4547 } 4548 4549 // If the caller didn't request filter information, 4550 // drop them now so we don't have to 4551 // marshall/unmarshall it. 4552 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 4553 N = results.size(); 4554 for (int i=0; i<N; i++) { 4555 results.get(i).filter = null; 4556 } 4557 } 4558 4559 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 4560 return results; 4561 } 4562 4563 @Override 4564 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 4565 int userId) { 4566 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4567 ComponentName comp = intent.getComponent(); 4568 if (comp == null) { 4569 if (intent.getSelector() != null) { 4570 intent = intent.getSelector(); 4571 comp = intent.getComponent(); 4572 } 4573 } 4574 if (comp != null) { 4575 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4576 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 4577 if (ai != null) { 4578 ResolveInfo ri = new ResolveInfo(); 4579 ri.activityInfo = ai; 4580 list.add(ri); 4581 } 4582 return list; 4583 } 4584 4585 // reader 4586 synchronized (mPackages) { 4587 String pkgName = intent.getPackage(); 4588 if (pkgName == null) { 4589 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 4590 } 4591 final PackageParser.Package pkg = mPackages.get(pkgName); 4592 if (pkg != null) { 4593 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 4594 userId); 4595 } 4596 return null; 4597 } 4598 } 4599 4600 @Override 4601 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 4602 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 4603 if (!sUserManager.exists(userId)) return null; 4604 if (query != null) { 4605 if (query.size() >= 1) { 4606 // If there is more than one service with the same priority, 4607 // just arbitrarily pick the first one. 4608 return query.get(0); 4609 } 4610 } 4611 return null; 4612 } 4613 4614 @Override 4615 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 4616 int userId) { 4617 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4618 ComponentName comp = intent.getComponent(); 4619 if (comp == null) { 4620 if (intent.getSelector() != null) { 4621 intent = intent.getSelector(); 4622 comp = intent.getComponent(); 4623 } 4624 } 4625 if (comp != null) { 4626 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4627 final ServiceInfo si = getServiceInfo(comp, flags, userId); 4628 if (si != null) { 4629 final ResolveInfo ri = new ResolveInfo(); 4630 ri.serviceInfo = si; 4631 list.add(ri); 4632 } 4633 return list; 4634 } 4635 4636 // reader 4637 synchronized (mPackages) { 4638 String pkgName = intent.getPackage(); 4639 if (pkgName == null) { 4640 return mServices.queryIntent(intent, resolvedType, flags, userId); 4641 } 4642 final PackageParser.Package pkg = mPackages.get(pkgName); 4643 if (pkg != null) { 4644 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 4645 userId); 4646 } 4647 return null; 4648 } 4649 } 4650 4651 @Override 4652 public List<ResolveInfo> queryIntentContentProviders( 4653 Intent intent, String resolvedType, int flags, int userId) { 4654 if (!sUserManager.exists(userId)) return Collections.emptyList(); 4655 ComponentName comp = intent.getComponent(); 4656 if (comp == null) { 4657 if (intent.getSelector() != null) { 4658 intent = intent.getSelector(); 4659 comp = intent.getComponent(); 4660 } 4661 } 4662 if (comp != null) { 4663 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 4664 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 4665 if (pi != null) { 4666 final ResolveInfo ri = new ResolveInfo(); 4667 ri.providerInfo = pi; 4668 list.add(ri); 4669 } 4670 return list; 4671 } 4672 4673 // reader 4674 synchronized (mPackages) { 4675 String pkgName = intent.getPackage(); 4676 if (pkgName == null) { 4677 return mProviders.queryIntent(intent, resolvedType, flags, userId); 4678 } 4679 final PackageParser.Package pkg = mPackages.get(pkgName); 4680 if (pkg != null) { 4681 return mProviders.queryIntentForPackage( 4682 intent, resolvedType, flags, pkg.providers, userId); 4683 } 4684 return null; 4685 } 4686 } 4687 4688 @Override 4689 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 4690 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4691 4692 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 4693 4694 // writer 4695 synchronized (mPackages) { 4696 ArrayList<PackageInfo> list; 4697 if (listUninstalled) { 4698 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 4699 for (PackageSetting ps : mSettings.mPackages.values()) { 4700 PackageInfo pi; 4701 if (ps.pkg != null) { 4702 pi = generatePackageInfo(ps.pkg, flags, userId); 4703 } else { 4704 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4705 } 4706 if (pi != null) { 4707 list.add(pi); 4708 } 4709 } 4710 } else { 4711 list = new ArrayList<PackageInfo>(mPackages.size()); 4712 for (PackageParser.Package p : mPackages.values()) { 4713 PackageInfo pi = generatePackageInfo(p, flags, userId); 4714 if (pi != null) { 4715 list.add(pi); 4716 } 4717 } 4718 } 4719 4720 return new ParceledListSlice<PackageInfo>(list); 4721 } 4722 } 4723 4724 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 4725 String[] permissions, boolean[] tmp, int flags, int userId) { 4726 int numMatch = 0; 4727 final PermissionsState permissionsState = ps.getPermissionsState(); 4728 for (int i=0; i<permissions.length; i++) { 4729 final String permission = permissions[i]; 4730 if (permissionsState.hasPermission(permission, userId)) { 4731 tmp[i] = true; 4732 numMatch++; 4733 } else { 4734 tmp[i] = false; 4735 } 4736 } 4737 if (numMatch == 0) { 4738 return; 4739 } 4740 PackageInfo pi; 4741 if (ps.pkg != null) { 4742 pi = generatePackageInfo(ps.pkg, flags, userId); 4743 } else { 4744 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 4745 } 4746 // The above might return null in cases of uninstalled apps or install-state 4747 // skew across users/profiles. 4748 if (pi != null) { 4749 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 4750 if (numMatch == permissions.length) { 4751 pi.requestedPermissions = permissions; 4752 } else { 4753 pi.requestedPermissions = new String[numMatch]; 4754 numMatch = 0; 4755 for (int i=0; i<permissions.length; i++) { 4756 if (tmp[i]) { 4757 pi.requestedPermissions[numMatch] = permissions[i]; 4758 numMatch++; 4759 } 4760 } 4761 } 4762 } 4763 list.add(pi); 4764 } 4765 } 4766 4767 @Override 4768 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 4769 String[] permissions, int flags, int userId) { 4770 if (!sUserManager.exists(userId)) return null; 4771 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4772 4773 // writer 4774 synchronized (mPackages) { 4775 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 4776 boolean[] tmpBools = new boolean[permissions.length]; 4777 if (listUninstalled) { 4778 for (PackageSetting ps : mSettings.mPackages.values()) { 4779 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 4780 } 4781 } else { 4782 for (PackageParser.Package pkg : mPackages.values()) { 4783 PackageSetting ps = (PackageSetting)pkg.mExtras; 4784 if (ps != null) { 4785 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 4786 userId); 4787 } 4788 } 4789 } 4790 4791 return new ParceledListSlice<PackageInfo>(list); 4792 } 4793 } 4794 4795 @Override 4796 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 4797 if (!sUserManager.exists(userId)) return null; 4798 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 4799 4800 // writer 4801 synchronized (mPackages) { 4802 ArrayList<ApplicationInfo> list; 4803 if (listUninstalled) { 4804 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 4805 for (PackageSetting ps : mSettings.mPackages.values()) { 4806 ApplicationInfo ai; 4807 if (ps.pkg != null) { 4808 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 4809 ps.readUserState(userId), userId); 4810 } else { 4811 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 4812 } 4813 if (ai != null) { 4814 list.add(ai); 4815 } 4816 } 4817 } else { 4818 list = new ArrayList<ApplicationInfo>(mPackages.size()); 4819 for (PackageParser.Package p : mPackages.values()) { 4820 if (p.mExtras != null) { 4821 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4822 ((PackageSetting)p.mExtras).readUserState(userId), userId); 4823 if (ai != null) { 4824 list.add(ai); 4825 } 4826 } 4827 } 4828 } 4829 4830 return new ParceledListSlice<ApplicationInfo>(list); 4831 } 4832 } 4833 4834 public List<ApplicationInfo> getPersistentApplications(int flags) { 4835 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 4836 4837 // reader 4838 synchronized (mPackages) { 4839 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 4840 final int userId = UserHandle.getCallingUserId(); 4841 while (i.hasNext()) { 4842 final PackageParser.Package p = i.next(); 4843 if (p.applicationInfo != null 4844 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 4845 && (!mSafeMode || isSystemApp(p))) { 4846 PackageSetting ps = mSettings.mPackages.get(p.packageName); 4847 if (ps != null) { 4848 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 4849 ps.readUserState(userId), userId); 4850 if (ai != null) { 4851 finalList.add(ai); 4852 } 4853 } 4854 } 4855 } 4856 } 4857 4858 return finalList; 4859 } 4860 4861 @Override 4862 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 4863 if (!sUserManager.exists(userId)) return null; 4864 // reader 4865 synchronized (mPackages) { 4866 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 4867 PackageSetting ps = provider != null 4868 ? mSettings.mPackages.get(provider.owner.packageName) 4869 : null; 4870 return ps != null 4871 && mSettings.isEnabledLPr(provider.info, flags, userId) 4872 && (!mSafeMode || (provider.info.applicationInfo.flags 4873 &ApplicationInfo.FLAG_SYSTEM) != 0) 4874 ? PackageParser.generateProviderInfo(provider, flags, 4875 ps.readUserState(userId), userId) 4876 : null; 4877 } 4878 } 4879 4880 /** 4881 * @deprecated 4882 */ 4883 @Deprecated 4884 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 4885 // reader 4886 synchronized (mPackages) { 4887 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 4888 .entrySet().iterator(); 4889 final int userId = UserHandle.getCallingUserId(); 4890 while (i.hasNext()) { 4891 Map.Entry<String, PackageParser.Provider> entry = i.next(); 4892 PackageParser.Provider p = entry.getValue(); 4893 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4894 4895 if (ps != null && p.syncable 4896 && (!mSafeMode || (p.info.applicationInfo.flags 4897 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 4898 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 4899 ps.readUserState(userId), userId); 4900 if (info != null) { 4901 outNames.add(entry.getKey()); 4902 outInfo.add(info); 4903 } 4904 } 4905 } 4906 } 4907 } 4908 4909 @Override 4910 public List<ProviderInfo> queryContentProviders(String processName, 4911 int uid, int flags) { 4912 ArrayList<ProviderInfo> finalList = null; 4913 // reader 4914 synchronized (mPackages) { 4915 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 4916 final int userId = processName != null ? 4917 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 4918 while (i.hasNext()) { 4919 final PackageParser.Provider p = i.next(); 4920 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4921 if (ps != null && p.info.authority != null 4922 && (processName == null 4923 || (p.info.processName.equals(processName) 4924 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 4925 && mSettings.isEnabledLPr(p.info, flags, userId) 4926 && (!mSafeMode 4927 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 4928 if (finalList == null) { 4929 finalList = new ArrayList<ProviderInfo>(3); 4930 } 4931 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 4932 ps.readUserState(userId), userId); 4933 if (info != null) { 4934 finalList.add(info); 4935 } 4936 } 4937 } 4938 } 4939 4940 if (finalList != null) { 4941 Collections.sort(finalList, mProviderInitOrderSorter); 4942 } 4943 4944 return finalList; 4945 } 4946 4947 @Override 4948 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 4949 int flags) { 4950 // reader 4951 synchronized (mPackages) { 4952 final PackageParser.Instrumentation i = mInstrumentation.get(name); 4953 return PackageParser.generateInstrumentationInfo(i, flags); 4954 } 4955 } 4956 4957 @Override 4958 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 4959 int flags) { 4960 ArrayList<InstrumentationInfo> finalList = 4961 new ArrayList<InstrumentationInfo>(); 4962 4963 // reader 4964 synchronized (mPackages) { 4965 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 4966 while (i.hasNext()) { 4967 final PackageParser.Instrumentation p = i.next(); 4968 if (targetPackage == null 4969 || targetPackage.equals(p.info.targetPackage)) { 4970 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 4971 flags); 4972 if (ii != null) { 4973 finalList.add(ii); 4974 } 4975 } 4976 } 4977 } 4978 4979 return finalList; 4980 } 4981 4982 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 4983 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 4984 if (overlays == null) { 4985 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 4986 return; 4987 } 4988 for (PackageParser.Package opkg : overlays.values()) { 4989 // Not much to do if idmap fails: we already logged the error 4990 // and we certainly don't want to abort installation of pkg simply 4991 // because an overlay didn't fit properly. For these reasons, 4992 // ignore the return value of createIdmapForPackagePairLI. 4993 createIdmapForPackagePairLI(pkg, opkg); 4994 } 4995 } 4996 4997 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 4998 PackageParser.Package opkg) { 4999 if (!opkg.mTrustedOverlay) { 5000 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 5001 opkg.baseCodePath + ": overlay not trusted"); 5002 return false; 5003 } 5004 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 5005 if (overlaySet == null) { 5006 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 5007 opkg.baseCodePath + " but target package has no known overlays"); 5008 return false; 5009 } 5010 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 5011 // TODO: generate idmap for split APKs 5012 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 5013 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 5014 + opkg.baseCodePath); 5015 return false; 5016 } 5017 PackageParser.Package[] overlayArray = 5018 overlaySet.values().toArray(new PackageParser.Package[0]); 5019 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 5020 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 5021 return p1.mOverlayPriority - p2.mOverlayPriority; 5022 } 5023 }; 5024 Arrays.sort(overlayArray, cmp); 5025 5026 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 5027 int i = 0; 5028 for (PackageParser.Package p : overlayArray) { 5029 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 5030 } 5031 return true; 5032 } 5033 5034 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 5035 final File[] files = dir.listFiles(); 5036 if (ArrayUtils.isEmpty(files)) { 5037 Log.d(TAG, "No files in app dir " + dir); 5038 return; 5039 } 5040 5041 if (DEBUG_PACKAGE_SCANNING) { 5042 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 5043 + " flags=0x" + Integer.toHexString(parseFlags)); 5044 } 5045 5046 for (File file : files) { 5047 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 5048 && !PackageInstallerService.isStageName(file.getName()); 5049 if (!isPackage) { 5050 // Ignore entries which are not packages 5051 continue; 5052 } 5053 try { 5054 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 5055 scanFlags, currentTime, null); 5056 } catch (PackageManagerException e) { 5057 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 5058 5059 // Delete invalid userdata apps 5060 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 5061 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 5062 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 5063 if (file.isDirectory()) { 5064 mInstaller.rmPackageDir(file.getAbsolutePath()); 5065 } else { 5066 file.delete(); 5067 } 5068 } 5069 } 5070 } 5071 } 5072 5073 private static File getSettingsProblemFile() { 5074 File dataDir = Environment.getDataDirectory(); 5075 File systemDir = new File(dataDir, "system"); 5076 File fname = new File(systemDir, "uiderrors.txt"); 5077 return fname; 5078 } 5079 5080 static void reportSettingsProblem(int priority, String msg) { 5081 logCriticalInfo(priority, msg); 5082 } 5083 5084 static void logCriticalInfo(int priority, String msg) { 5085 Slog.println(priority, TAG, msg); 5086 EventLogTags.writePmCriticalInfo(msg); 5087 try { 5088 File fname = getSettingsProblemFile(); 5089 FileOutputStream out = new FileOutputStream(fname, true); 5090 PrintWriter pw = new FastPrintWriter(out); 5091 SimpleDateFormat formatter = new SimpleDateFormat(); 5092 String dateString = formatter.format(new Date(System.currentTimeMillis())); 5093 pw.println(dateString + ": " + msg); 5094 pw.close(); 5095 FileUtils.setPermissions( 5096 fname.toString(), 5097 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 5098 -1, -1); 5099 } catch (java.io.IOException e) { 5100 } 5101 } 5102 5103 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 5104 PackageParser.Package pkg, File srcFile, int parseFlags) 5105 throws PackageManagerException { 5106 if (ps != null 5107 && ps.codePath.equals(srcFile) 5108 && ps.timeStamp == srcFile.lastModified() 5109 && !isCompatSignatureUpdateNeeded(pkg) 5110 && !isRecoverSignatureUpdateNeeded(pkg)) { 5111 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 5112 if (ps.signatures.mSignatures != null 5113 && ps.signatures.mSignatures.length != 0 5114 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) { 5115 // Optimization: reuse the existing cached certificates 5116 // if the package appears to be unchanged. 5117 pkg.mSignatures = ps.signatures.mSignatures; 5118 KeySetManagerService ksms = mSettings.mKeySetManagerService; 5119 synchronized (mPackages) { 5120 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 5121 } 5122 return; 5123 } 5124 5125 Slog.w(TAG, "PackageSetting for " + ps.name 5126 + " is missing signatures. Collecting certs again to recover them."); 5127 } else { 5128 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 5129 } 5130 5131 try { 5132 pp.collectCertificates(pkg, parseFlags); 5133 pp.collectManifestDigest(pkg); 5134 } catch (PackageParserException e) { 5135 throw PackageManagerException.from(e); 5136 } 5137 } 5138 5139 /* 5140 * Scan a package and return the newly parsed package. 5141 * Returns null in case of errors and the error code is stored in mLastScanError 5142 */ 5143 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 5144 long currentTime, UserHandle user) throws PackageManagerException { 5145 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 5146 parseFlags |= mDefParseFlags; 5147 PackageParser pp = new PackageParser(); 5148 pp.setSeparateProcesses(mSeparateProcesses); 5149 pp.setOnlyCoreApps(mOnlyCore); 5150 pp.setDisplayMetrics(mMetrics); 5151 5152 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 5153 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 5154 } 5155 5156 final PackageParser.Package pkg; 5157 try { 5158 pkg = pp.parsePackage(scanFile, parseFlags); 5159 } catch (PackageParserException e) { 5160 throw PackageManagerException.from(e); 5161 } 5162 5163 PackageSetting ps = null; 5164 PackageSetting updatedPkg; 5165 // reader 5166 synchronized (mPackages) { 5167 // Look to see if we already know about this package. 5168 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 5169 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 5170 // This package has been renamed to its original name. Let's 5171 // use that. 5172 ps = mSettings.peekPackageLPr(oldName); 5173 } 5174 // If there was no original package, see one for the real package name. 5175 if (ps == null) { 5176 ps = mSettings.peekPackageLPr(pkg.packageName); 5177 } 5178 // Check to see if this package could be hiding/updating a system 5179 // package. Must look for it either under the original or real 5180 // package name depending on our state. 5181 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 5182 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 5183 } 5184 boolean updatedPkgBetter = false; 5185 // First check if this is a system package that may involve an update 5186 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5187 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 5188 // it needs to drop FLAG_PRIVILEGED. 5189 if (locationIsPrivileged(scanFile)) { 5190 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5191 } else { 5192 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5193 } 5194 5195 if (ps != null && !ps.codePath.equals(scanFile)) { 5196 // The path has changed from what was last scanned... check the 5197 // version of the new path against what we have stored to determine 5198 // what to do. 5199 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 5200 if (pkg.mVersionCode <= ps.versionCode) { 5201 // The system package has been updated and the code path does not match 5202 // Ignore entry. Skip it. 5203 Slog.i(TAG, "Package " + ps.name + " at " + scanFile 5204 + " ignored: updated version " + ps.versionCode 5205 + " better than this " + pkg.mVersionCode); 5206 if (!updatedPkg.codePath.equals(scanFile)) { 5207 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 5208 + ps.name + " changing from " + updatedPkg.codePathString 5209 + " to " + scanFile); 5210 updatedPkg.codePath = scanFile; 5211 updatedPkg.codePathString = scanFile.toString(); 5212 updatedPkg.resourcePath = scanFile; 5213 updatedPkg.resourcePathString = scanFile.toString(); 5214 } 5215 updatedPkg.pkg = pkg; 5216 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null); 5217 } else { 5218 // The current app on the system partition is better than 5219 // what we have updated to on the data partition; switch 5220 // back to the system partition version. 5221 // At this point, its safely assumed that package installation for 5222 // apps in system partition will go through. If not there won't be a working 5223 // version of the app 5224 // writer 5225 synchronized (mPackages) { 5226 // Just remove the loaded entries from package lists. 5227 mPackages.remove(ps.name); 5228 } 5229 5230 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5231 + " reverting from " + ps.codePathString 5232 + ": new version " + pkg.mVersionCode 5233 + " better than installed " + ps.versionCode); 5234 5235 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5236 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5237 synchronized (mInstallLock) { 5238 args.cleanUpResourcesLI(); 5239 } 5240 synchronized (mPackages) { 5241 mSettings.enableSystemPackageLPw(ps.name); 5242 } 5243 updatedPkgBetter = true; 5244 } 5245 } 5246 } 5247 5248 if (updatedPkg != null) { 5249 // An updated system app will not have the PARSE_IS_SYSTEM flag set 5250 // initially 5251 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 5252 5253 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 5254 // flag set initially 5255 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 5256 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 5257 } 5258 } 5259 5260 // Verify certificates against what was last scanned 5261 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 5262 5263 /* 5264 * A new system app appeared, but we already had a non-system one of the 5265 * same name installed earlier. 5266 */ 5267 boolean shouldHideSystemApp = false; 5268 if (updatedPkg == null && ps != null 5269 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 5270 /* 5271 * Check to make sure the signatures match first. If they don't, 5272 * wipe the installed application and its data. 5273 */ 5274 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 5275 != PackageManager.SIGNATURE_MATCH) { 5276 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 5277 + " signatures don't match existing userdata copy; removing"); 5278 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 5279 ps = null; 5280 } else { 5281 /* 5282 * If the newly-added system app is an older version than the 5283 * already installed version, hide it. It will be scanned later 5284 * and re-added like an update. 5285 */ 5286 if (pkg.mVersionCode <= ps.versionCode) { 5287 shouldHideSystemApp = true; 5288 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 5289 + " but new version " + pkg.mVersionCode + " better than installed " 5290 + ps.versionCode + "; hiding system"); 5291 } else { 5292 /* 5293 * The newly found system app is a newer version that the 5294 * one previously installed. Simply remove the 5295 * already-installed application and replace it with our own 5296 * while keeping the application data. 5297 */ 5298 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 5299 + " reverting from " + ps.codePathString + ": new version " 5300 + pkg.mVersionCode + " better than installed " + ps.versionCode); 5301 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 5302 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 5303 synchronized (mInstallLock) { 5304 args.cleanUpResourcesLI(); 5305 } 5306 } 5307 } 5308 } 5309 5310 // The apk is forward locked (not public) if its code and resources 5311 // are kept in different files. (except for app in either system or 5312 // vendor path). 5313 // TODO grab this value from PackageSettings 5314 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5315 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 5316 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 5317 } 5318 } 5319 5320 // TODO: extend to support forward-locked splits 5321 String resourcePath = null; 5322 String baseResourcePath = null; 5323 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 5324 if (ps != null && ps.resourcePathString != null) { 5325 resourcePath = ps.resourcePathString; 5326 baseResourcePath = ps.resourcePathString; 5327 } else { 5328 // Should not happen at all. Just log an error. 5329 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 5330 } 5331 } else { 5332 resourcePath = pkg.codePath; 5333 baseResourcePath = pkg.baseCodePath; 5334 } 5335 5336 // Set application objects path explicitly. 5337 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 5338 pkg.applicationInfo.setCodePath(pkg.codePath); 5339 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 5340 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 5341 pkg.applicationInfo.setResourcePath(resourcePath); 5342 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 5343 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 5344 5345 // Note that we invoke the following method only if we are about to unpack an application 5346 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 5347 | SCAN_UPDATE_SIGNATURE, currentTime, user); 5348 5349 /* 5350 * If the system app should be overridden by a previously installed 5351 * data, hide the system app now and let the /data/app scan pick it up 5352 * again. 5353 */ 5354 if (shouldHideSystemApp) { 5355 synchronized (mPackages) { 5356 /* 5357 * We have to grant systems permissions before we hide, because 5358 * grantPermissions will assume the package update is trying to 5359 * expand its permissions. 5360 */ 5361 grantPermissionsLPw(pkg, true, pkg.packageName); 5362 mSettings.disableSystemPackageLPw(pkg.packageName); 5363 } 5364 } 5365 5366 return scannedPkg; 5367 } 5368 5369 private static String fixProcessName(String defProcessName, 5370 String processName, int uid) { 5371 if (processName == null) { 5372 return defProcessName; 5373 } 5374 return processName; 5375 } 5376 5377 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 5378 throws PackageManagerException { 5379 if (pkgSetting.signatures.mSignatures != null) { 5380 // Already existing package. Make sure signatures match 5381 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 5382 == PackageManager.SIGNATURE_MATCH; 5383 if (!match) { 5384 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 5385 == PackageManager.SIGNATURE_MATCH; 5386 } 5387 if (!match) { 5388 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 5389 == PackageManager.SIGNATURE_MATCH; 5390 } 5391 if (!match) { 5392 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5393 + pkg.packageName + " signatures do not match the " 5394 + "previously installed version; ignoring!"); 5395 } 5396 } 5397 5398 // Check for shared user signatures 5399 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 5400 // Already existing package. Make sure signatures match 5401 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5402 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 5403 if (!match) { 5404 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 5405 == PackageManager.SIGNATURE_MATCH; 5406 } 5407 if (!match) { 5408 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 5409 == PackageManager.SIGNATURE_MATCH; 5410 } 5411 if (!match) { 5412 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 5413 "Package " + pkg.packageName 5414 + " has no signatures that match those in shared user " 5415 + pkgSetting.sharedUser.name + "; ignoring!"); 5416 } 5417 } 5418 } 5419 5420 /** 5421 * Enforces that only the system UID or root's UID can call a method exposed 5422 * via Binder. 5423 * 5424 * @param message used as message if SecurityException is thrown 5425 * @throws SecurityException if the caller is not system or root 5426 */ 5427 private static final void enforceSystemOrRoot(String message) { 5428 final int uid = Binder.getCallingUid(); 5429 if (uid != Process.SYSTEM_UID && uid != 0) { 5430 throw new SecurityException(message); 5431 } 5432 } 5433 5434 @Override 5435 public void performBootDexOpt() { 5436 enforceSystemOrRoot("Only the system can request dexopt be performed"); 5437 5438 // Before everything else, see whether we need to fstrim. 5439 try { 5440 IMountService ms = PackageHelper.getMountService(); 5441 if (ms != null) { 5442 final boolean isUpgrade = isUpgrade(); 5443 boolean doTrim = isUpgrade; 5444 if (doTrim) { 5445 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 5446 } else { 5447 final long interval = android.provider.Settings.Global.getLong( 5448 mContext.getContentResolver(), 5449 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 5450 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 5451 if (interval > 0) { 5452 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 5453 if (timeSinceLast > interval) { 5454 doTrim = true; 5455 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 5456 + "; running immediately"); 5457 } 5458 } 5459 } 5460 if (doTrim) { 5461 if (!isFirstBoot()) { 5462 try { 5463 ActivityManagerNative.getDefault().showBootMessage( 5464 mContext.getResources().getString( 5465 R.string.android_upgrading_fstrim), true); 5466 } catch (RemoteException e) { 5467 } 5468 } 5469 ms.runMaintenance(); 5470 } 5471 } else { 5472 Slog.e(TAG, "Mount service unavailable!"); 5473 } 5474 } catch (RemoteException e) { 5475 // Can't happen; MountService is local 5476 } 5477 5478 final ArraySet<PackageParser.Package> pkgs; 5479 synchronized (mPackages) { 5480 pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages(); 5481 } 5482 5483 if (pkgs != null) { 5484 // Sort apps by importance for dexopt ordering. Important apps are given more priority 5485 // in case the device runs out of space. 5486 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 5487 // Give priority to core apps. 5488 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5489 PackageParser.Package pkg = it.next(); 5490 if (pkg.coreApp) { 5491 if (DEBUG_DEXOPT) { 5492 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 5493 } 5494 sortedPkgs.add(pkg); 5495 it.remove(); 5496 } 5497 } 5498 // Give priority to system apps that listen for pre boot complete. 5499 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 5500 ArraySet<String> pkgNames = getPackageNamesForIntent(intent); 5501 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5502 PackageParser.Package pkg = it.next(); 5503 if (pkgNames.contains(pkg.packageName)) { 5504 if (DEBUG_DEXOPT) { 5505 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 5506 } 5507 sortedPkgs.add(pkg); 5508 it.remove(); 5509 } 5510 } 5511 // Give priority to system apps. 5512 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5513 PackageParser.Package pkg = it.next(); 5514 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { 5515 if (DEBUG_DEXOPT) { 5516 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName); 5517 } 5518 sortedPkgs.add(pkg); 5519 it.remove(); 5520 } 5521 } 5522 // Give priority to updated system apps. 5523 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5524 PackageParser.Package pkg = it.next(); 5525 if (pkg.isUpdatedSystemApp()) { 5526 if (DEBUG_DEXOPT) { 5527 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName); 5528 } 5529 sortedPkgs.add(pkg); 5530 it.remove(); 5531 } 5532 } 5533 // Give priority to apps that listen for boot complete. 5534 intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 5535 pkgNames = getPackageNamesForIntent(intent); 5536 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 5537 PackageParser.Package pkg = it.next(); 5538 if (pkgNames.contains(pkg.packageName)) { 5539 if (DEBUG_DEXOPT) { 5540 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName); 5541 } 5542 sortedPkgs.add(pkg); 5543 it.remove(); 5544 } 5545 } 5546 // Filter out packages that aren't recently used. 5547 filterRecentlyUsedApps(pkgs); 5548 // Add all remaining apps. 5549 for (PackageParser.Package pkg : pkgs) { 5550 if (DEBUG_DEXOPT) { 5551 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 5552 } 5553 sortedPkgs.add(pkg); 5554 } 5555 5556 // If we want to be lazy, filter everything that wasn't recently used. 5557 if (mLazyDexOpt) { 5558 filterRecentlyUsedApps(sortedPkgs); 5559 } 5560 5561 int i = 0; 5562 int total = sortedPkgs.size(); 5563 File dataDir = Environment.getDataDirectory(); 5564 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 5565 if (lowThreshold == 0) { 5566 throw new IllegalStateException("Invalid low memory threshold"); 5567 } 5568 for (PackageParser.Package pkg : sortedPkgs) { 5569 long usableSpace = dataDir.getUsableSpace(); 5570 if (usableSpace < lowThreshold) { 5571 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 5572 break; 5573 } 5574 performBootDexOpt(pkg, ++i, total); 5575 } 5576 } 5577 } 5578 5579 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 5580 // Filter out packages that aren't recently used. 5581 // 5582 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 5583 // should do a full dexopt. 5584 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 5585 int total = pkgs.size(); 5586 int skipped = 0; 5587 long now = System.currentTimeMillis(); 5588 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 5589 PackageParser.Package pkg = i.next(); 5590 long then = pkg.mLastPackageUsageTimeInMills; 5591 if (then + mDexOptLRUThresholdInMills < now) { 5592 if (DEBUG_DEXOPT) { 5593 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 5594 ((then == 0) ? "never" : new Date(then))); 5595 } 5596 i.remove(); 5597 skipped++; 5598 } 5599 } 5600 if (DEBUG_DEXOPT) { 5601 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 5602 } 5603 } 5604 } 5605 5606 private ArraySet<String> getPackageNamesForIntent(Intent intent) { 5607 List<ResolveInfo> ris = null; 5608 try { 5609 ris = AppGlobals.getPackageManager().queryIntentReceivers( 5610 intent, null, 0, UserHandle.USER_OWNER); 5611 } catch (RemoteException e) { 5612 } 5613 ArraySet<String> pkgNames = new ArraySet<String>(); 5614 if (ris != null) { 5615 for (ResolveInfo ri : ris) { 5616 pkgNames.add(ri.activityInfo.packageName); 5617 } 5618 } 5619 return pkgNames; 5620 } 5621 5622 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 5623 if (DEBUG_DEXOPT) { 5624 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 5625 } 5626 if (!isFirstBoot()) { 5627 try { 5628 ActivityManagerNative.getDefault().showBootMessage( 5629 mContext.getResources().getString(R.string.android_upgrading_apk, 5630 curr, total), true); 5631 } catch (RemoteException e) { 5632 } 5633 } 5634 PackageParser.Package p = pkg; 5635 synchronized (mInstallLock) { 5636 mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, 5637 false /* force dex */, false /* defer */, true /* include dependencies */); 5638 } 5639 } 5640 5641 @Override 5642 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 5643 return performDexOpt(packageName, instructionSet, false); 5644 } 5645 5646 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) { 5647 boolean dexopt = mLazyDexOpt || backgroundDexopt; 5648 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 5649 if (!dexopt && !updateUsage) { 5650 // We aren't going to dexopt or update usage, so bail early. 5651 return false; 5652 } 5653 PackageParser.Package p; 5654 final String targetInstructionSet; 5655 synchronized (mPackages) { 5656 p = mPackages.get(packageName); 5657 if (p == null) { 5658 return false; 5659 } 5660 if (updateUsage) { 5661 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 5662 } 5663 mPackageUsage.write(false); 5664 if (!dexopt) { 5665 // We aren't going to dexopt, so bail early. 5666 return false; 5667 } 5668 5669 targetInstructionSet = instructionSet != null ? instructionSet : 5670 getPrimaryInstructionSet(p.applicationInfo); 5671 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 5672 return false; 5673 } 5674 } 5675 5676 synchronized (mInstallLock) { 5677 final String[] instructionSets = new String[] { targetInstructionSet }; 5678 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, 5679 false /* forceDex */, false /* defer */, true /* inclDependencies */); 5680 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 5681 } 5682 } 5683 5684 public ArraySet<String> getPackagesThatNeedDexOpt() { 5685 ArraySet<String> pkgs = null; 5686 synchronized (mPackages) { 5687 for (PackageParser.Package p : mPackages.values()) { 5688 if (DEBUG_DEXOPT) { 5689 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 5690 } 5691 if (!p.mDexOptPerformed.isEmpty()) { 5692 continue; 5693 } 5694 if (pkgs == null) { 5695 pkgs = new ArraySet<String>(); 5696 } 5697 pkgs.add(p.packageName); 5698 } 5699 } 5700 return pkgs; 5701 } 5702 5703 public void shutdown() { 5704 mPackageUsage.write(true); 5705 } 5706 5707 @Override 5708 public void forceDexOpt(String packageName) { 5709 enforceSystemOrRoot("forceDexOpt"); 5710 5711 PackageParser.Package pkg; 5712 synchronized (mPackages) { 5713 pkg = mPackages.get(packageName); 5714 if (pkg == null) { 5715 throw new IllegalArgumentException("Missing package: " + packageName); 5716 } 5717 } 5718 5719 synchronized (mInstallLock) { 5720 final String[] instructionSets = new String[] { 5721 getPrimaryInstructionSet(pkg.applicationInfo) }; 5722 final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, 5723 true /*forceDex*/, false /* defer */, true /* inclDependencies */); 5724 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 5725 throw new IllegalStateException("Failed to dexopt: " + res); 5726 } 5727 } 5728 } 5729 5730 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 5731 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 5732 Slog.w(TAG, "Unable to update from " + oldPkg.name 5733 + " to " + newPkg.packageName 5734 + ": old package not in system partition"); 5735 return false; 5736 } else if (mPackages.get(oldPkg.name) != null) { 5737 Slog.w(TAG, "Unable to update from " + oldPkg.name 5738 + " to " + newPkg.packageName 5739 + ": old package still exists"); 5740 return false; 5741 } 5742 return true; 5743 } 5744 5745 private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) { 5746 int[] users = sUserManager.getUserIds(); 5747 int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo); 5748 if (res < 0) { 5749 return res; 5750 } 5751 for (int user : users) { 5752 if (user != 0) { 5753 res = mInstaller.createUserData(volumeUuid, packageName, 5754 UserHandle.getUid(user, uid), user, seinfo); 5755 if (res < 0) { 5756 return res; 5757 } 5758 } 5759 } 5760 return res; 5761 } 5762 5763 private int removeDataDirsLI(String volumeUuid, String packageName) { 5764 int[] users = sUserManager.getUserIds(); 5765 int res = 0; 5766 for (int user : users) { 5767 int resInner = mInstaller.remove(volumeUuid, packageName, user); 5768 if (resInner < 0) { 5769 res = resInner; 5770 } 5771 } 5772 5773 return res; 5774 } 5775 5776 private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 5777 int[] users = sUserManager.getUserIds(); 5778 int res = 0; 5779 for (int user : users) { 5780 int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user); 5781 if (resInner < 0) { 5782 res = resInner; 5783 } 5784 } 5785 return res; 5786 } 5787 5788 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 5789 PackageParser.Package changingLib) { 5790 if (file.path != null) { 5791 usesLibraryFiles.add(file.path); 5792 return; 5793 } 5794 PackageParser.Package p = mPackages.get(file.apk); 5795 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 5796 // If we are doing this while in the middle of updating a library apk, 5797 // then we need to make sure to use that new apk for determining the 5798 // dependencies here. (We haven't yet finished committing the new apk 5799 // to the package manager state.) 5800 if (p == null || p.packageName.equals(changingLib.packageName)) { 5801 p = changingLib; 5802 } 5803 } 5804 if (p != null) { 5805 usesLibraryFiles.addAll(p.getAllCodePaths()); 5806 } 5807 } 5808 5809 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 5810 PackageParser.Package changingLib) throws PackageManagerException { 5811 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 5812 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 5813 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 5814 for (int i=0; i<N; i++) { 5815 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 5816 if (file == null) { 5817 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 5818 "Package " + pkg.packageName + " requires unavailable shared library " 5819 + pkg.usesLibraries.get(i) + "; failing!"); 5820 } 5821 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5822 } 5823 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 5824 for (int i=0; i<N; i++) { 5825 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 5826 if (file == null) { 5827 Slog.w(TAG, "Package " + pkg.packageName 5828 + " desires unavailable shared library " 5829 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 5830 } else { 5831 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5832 } 5833 } 5834 N = usesLibraryFiles.size(); 5835 if (N > 0) { 5836 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 5837 } else { 5838 pkg.usesLibraryFiles = null; 5839 } 5840 } 5841 } 5842 5843 private static boolean hasString(List<String> list, List<String> which) { 5844 if (list == null) { 5845 return false; 5846 } 5847 for (int i=list.size()-1; i>=0; i--) { 5848 for (int j=which.size()-1; j>=0; j--) { 5849 if (which.get(j).equals(list.get(i))) { 5850 return true; 5851 } 5852 } 5853 } 5854 return false; 5855 } 5856 5857 private void updateAllSharedLibrariesLPw() { 5858 for (PackageParser.Package pkg : mPackages.values()) { 5859 try { 5860 updateSharedLibrariesLPw(pkg, null); 5861 } catch (PackageManagerException e) { 5862 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5863 } 5864 } 5865 } 5866 5867 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 5868 PackageParser.Package changingPkg) { 5869 ArrayList<PackageParser.Package> res = null; 5870 for (PackageParser.Package pkg : mPackages.values()) { 5871 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 5872 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 5873 if (res == null) { 5874 res = new ArrayList<PackageParser.Package>(); 5875 } 5876 res.add(pkg); 5877 try { 5878 updateSharedLibrariesLPw(pkg, changingPkg); 5879 } catch (PackageManagerException e) { 5880 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5881 } 5882 } 5883 } 5884 return res; 5885 } 5886 5887 /** 5888 * Derive the value of the {@code cpuAbiOverride} based on the provided 5889 * value and an optional stored value from the package settings. 5890 */ 5891 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 5892 String cpuAbiOverride = null; 5893 5894 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 5895 cpuAbiOverride = null; 5896 } else if (abiOverride != null) { 5897 cpuAbiOverride = abiOverride; 5898 } else if (settings != null) { 5899 cpuAbiOverride = settings.cpuAbiOverrideString; 5900 } 5901 5902 return cpuAbiOverride; 5903 } 5904 5905 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 5906 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5907 boolean success = false; 5908 try { 5909 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 5910 currentTime, user); 5911 success = true; 5912 return res; 5913 } finally { 5914 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5915 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 5916 } 5917 } 5918 } 5919 5920 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 5921 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5922 final File scanFile = new File(pkg.codePath); 5923 if (pkg.applicationInfo.getCodePath() == null || 5924 pkg.applicationInfo.getResourcePath() == null) { 5925 // Bail out. The resource and code paths haven't been set. 5926 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 5927 "Code and resource paths haven't been set correctly"); 5928 } 5929 5930 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5931 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 5932 } else { 5933 // Only allow system apps to be flagged as core apps. 5934 pkg.coreApp = false; 5935 } 5936 5937 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 5938 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 5939 } 5940 5941 if (mCustomResolverComponentName != null && 5942 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 5943 setUpCustomResolverActivity(pkg); 5944 } 5945 5946 if (pkg.packageName.equals("android")) { 5947 synchronized (mPackages) { 5948 if (mAndroidApplication != null) { 5949 Slog.w(TAG, "*************************************************"); 5950 Slog.w(TAG, "Core android package being redefined. Skipping."); 5951 Slog.w(TAG, " file=" + scanFile); 5952 Slog.w(TAG, "*************************************************"); 5953 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5954 "Core android package being redefined. Skipping."); 5955 } 5956 5957 // Set up information for our fall-back user intent resolution activity. 5958 mPlatformPackage = pkg; 5959 pkg.mVersionCode = mSdkVersion; 5960 mAndroidApplication = pkg.applicationInfo; 5961 5962 if (!mResolverReplaced) { 5963 mResolveActivity.applicationInfo = mAndroidApplication; 5964 mResolveActivity.name = ResolverActivity.class.getName(); 5965 mResolveActivity.packageName = mAndroidApplication.packageName; 5966 mResolveActivity.processName = "system:ui"; 5967 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5968 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 5969 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 5970 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 5971 mResolveActivity.exported = true; 5972 mResolveActivity.enabled = true; 5973 mResolveInfo.activityInfo = mResolveActivity; 5974 mResolveInfo.priority = 0; 5975 mResolveInfo.preferredOrder = 0; 5976 mResolveInfo.match = 0; 5977 mResolveComponentName = new ComponentName( 5978 mAndroidApplication.packageName, mResolveActivity.name); 5979 } 5980 } 5981 } 5982 5983 if (DEBUG_PACKAGE_SCANNING) { 5984 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5985 Log.d(TAG, "Scanning package " + pkg.packageName); 5986 } 5987 5988 if (mPackages.containsKey(pkg.packageName) 5989 || mSharedLibraries.containsKey(pkg.packageName)) { 5990 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5991 "Application package " + pkg.packageName 5992 + " already installed. Skipping duplicate."); 5993 } 5994 5995 // If we're only installing presumed-existing packages, require that the 5996 // scanned APK is both already known and at the path previously established 5997 // for it. Previously unknown packages we pick up normally, but if we have an 5998 // a priori expectation about this package's install presence, enforce it. 5999 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 6000 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 6001 if (known != null) { 6002 if (DEBUG_PACKAGE_SCANNING) { 6003 Log.d(TAG, "Examining " + pkg.codePath 6004 + " and requiring known paths " + known.codePathString 6005 + " & " + known.resourcePathString); 6006 } 6007 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 6008 || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { 6009 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 6010 "Application package " + pkg.packageName 6011 + " found at " + pkg.applicationInfo.getCodePath() 6012 + " but expected at " + known.codePathString + "; ignoring."); 6013 } 6014 } 6015 } 6016 6017 // Initialize package source and resource directories 6018 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 6019 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 6020 6021 SharedUserSetting suid = null; 6022 PackageSetting pkgSetting = null; 6023 6024 if (!isSystemApp(pkg)) { 6025 // Only system apps can use these features. 6026 pkg.mOriginalPackages = null; 6027 pkg.mRealPackage = null; 6028 pkg.mAdoptPermissions = null; 6029 } 6030 6031 // writer 6032 synchronized (mPackages) { 6033 if (pkg.mSharedUserId != null) { 6034 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 6035 if (suid == null) { 6036 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6037 "Creating application package " + pkg.packageName 6038 + " for shared user failed"); 6039 } 6040 if (DEBUG_PACKAGE_SCANNING) { 6041 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6042 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 6043 + "): packages=" + suid.packages); 6044 } 6045 } 6046 6047 // Check if we are renaming from an original package name. 6048 PackageSetting origPackage = null; 6049 String realName = null; 6050 if (pkg.mOriginalPackages != null) { 6051 // This package may need to be renamed to a previously 6052 // installed name. Let's check on that... 6053 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 6054 if (pkg.mOriginalPackages.contains(renamed)) { 6055 // This package had originally been installed as the 6056 // original name, and we have already taken care of 6057 // transitioning to the new one. Just update the new 6058 // one to continue using the old name. 6059 realName = pkg.mRealPackage; 6060 if (!pkg.packageName.equals(renamed)) { 6061 // Callers into this function may have already taken 6062 // care of renaming the package; only do it here if 6063 // it is not already done. 6064 pkg.setPackageName(renamed); 6065 } 6066 6067 } else { 6068 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 6069 if ((origPackage = mSettings.peekPackageLPr( 6070 pkg.mOriginalPackages.get(i))) != null) { 6071 // We do have the package already installed under its 6072 // original name... should we use it? 6073 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 6074 // New package is not compatible with original. 6075 origPackage = null; 6076 continue; 6077 } else if (origPackage.sharedUser != null) { 6078 // Make sure uid is compatible between packages. 6079 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 6080 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 6081 + " to " + pkg.packageName + ": old uid " 6082 + origPackage.sharedUser.name 6083 + " differs from " + pkg.mSharedUserId); 6084 origPackage = null; 6085 continue; 6086 } 6087 } else { 6088 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 6089 + pkg.packageName + " to old name " + origPackage.name); 6090 } 6091 break; 6092 } 6093 } 6094 } 6095 } 6096 6097 if (mTransferedPackages.contains(pkg.packageName)) { 6098 Slog.w(TAG, "Package " + pkg.packageName 6099 + " was transferred to another, but its .apk remains"); 6100 } 6101 6102 // Just create the setting, don't add it yet. For already existing packages 6103 // the PkgSetting exists already and doesn't have to be created. 6104 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 6105 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 6106 pkg.applicationInfo.primaryCpuAbi, 6107 pkg.applicationInfo.secondaryCpuAbi, 6108 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 6109 user, false); 6110 if (pkgSetting == null) { 6111 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6112 "Creating application package " + pkg.packageName + " failed"); 6113 } 6114 6115 if (pkgSetting.origPackage != null) { 6116 // If we are first transitioning from an original package, 6117 // fix up the new package's name now. We need to do this after 6118 // looking up the package under its new name, so getPackageLP 6119 // can take care of fiddling things correctly. 6120 pkg.setPackageName(origPackage.name); 6121 6122 // File a report about this. 6123 String msg = "New package " + pkgSetting.realName 6124 + " renamed to replace old package " + pkgSetting.name; 6125 reportSettingsProblem(Log.WARN, msg); 6126 6127 // Make a note of it. 6128 mTransferedPackages.add(origPackage.name); 6129 6130 // No longer need to retain this. 6131 pkgSetting.origPackage = null; 6132 } 6133 6134 if (realName != null) { 6135 // Make a note of it. 6136 mTransferedPackages.add(pkg.packageName); 6137 } 6138 6139 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 6140 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 6141 } 6142 6143 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6144 // Check all shared libraries and map to their actual file path. 6145 // We only do this here for apps not on a system dir, because those 6146 // are the only ones that can fail an install due to this. We 6147 // will take care of the system apps by updating all of their 6148 // library paths after the scan is done. 6149 updateSharedLibrariesLPw(pkg, null); 6150 } 6151 6152 if (mFoundPolicyFile) { 6153 SELinuxMMAC.assignSeinfoValue(pkg); 6154 } 6155 6156 pkg.applicationInfo.uid = pkgSetting.appId; 6157 pkg.mExtras = pkgSetting; 6158 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 6159 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 6160 // We just determined the app is signed correctly, so bring 6161 // over the latest parsed certs. 6162 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6163 } else { 6164 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6165 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6166 "Package " + pkg.packageName + " upgrade keys do not match the " 6167 + "previously installed version"); 6168 } else { 6169 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6170 String msg = "System package " + pkg.packageName 6171 + " signature changed; retaining data."; 6172 reportSettingsProblem(Log.WARN, msg); 6173 } 6174 } 6175 } else { 6176 try { 6177 verifySignaturesLP(pkgSetting, pkg); 6178 // We just determined the app is signed correctly, so bring 6179 // over the latest parsed certs. 6180 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6181 } catch (PackageManagerException e) { 6182 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6183 throw e; 6184 } 6185 // The signature has changed, but this package is in the system 6186 // image... let's recover! 6187 pkgSetting.signatures.mSignatures = pkg.mSignatures; 6188 // However... if this package is part of a shared user, but it 6189 // doesn't match the signature of the shared user, let's fail. 6190 // What this means is that you can't change the signatures 6191 // associated with an overall shared user, which doesn't seem all 6192 // that unreasonable. 6193 if (pkgSetting.sharedUser != null) { 6194 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6195 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 6196 throw new PackageManagerException( 6197 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 6198 "Signature mismatch for shared user : " 6199 + pkgSetting.sharedUser); 6200 } 6201 } 6202 // File a report about this. 6203 String msg = "System package " + pkg.packageName 6204 + " signature changed; retaining data."; 6205 reportSettingsProblem(Log.WARN, msg); 6206 } 6207 } 6208 // Verify that this new package doesn't have any content providers 6209 // that conflict with existing packages. Only do this if the 6210 // package isn't already installed, since we don't want to break 6211 // things that are installed. 6212 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 6213 final int N = pkg.providers.size(); 6214 int i; 6215 for (i=0; i<N; i++) { 6216 PackageParser.Provider p = pkg.providers.get(i); 6217 if (p.info.authority != null) { 6218 String names[] = p.info.authority.split(";"); 6219 for (int j = 0; j < names.length; j++) { 6220 if (mProvidersByAuthority.containsKey(names[j])) { 6221 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6222 final String otherPackageName = 6223 ((other != null && other.getComponentName() != null) ? 6224 other.getComponentName().getPackageName() : "?"); 6225 throw new PackageManagerException( 6226 INSTALL_FAILED_CONFLICTING_PROVIDER, 6227 "Can't install because provider name " + names[j] 6228 + " (in package " + pkg.applicationInfo.packageName 6229 + ") is already used by " + otherPackageName); 6230 } 6231 } 6232 } 6233 } 6234 } 6235 6236 if (pkg.mAdoptPermissions != null) { 6237 // This package wants to adopt ownership of permissions from 6238 // another package. 6239 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 6240 final String origName = pkg.mAdoptPermissions.get(i); 6241 final PackageSetting orig = mSettings.peekPackageLPr(origName); 6242 if (orig != null) { 6243 if (verifyPackageUpdateLPr(orig, pkg)) { 6244 Slog.i(TAG, "Adopting permissions from " + origName + " to " 6245 + pkg.packageName); 6246 mSettings.transferPermissionsLPw(origName, pkg.packageName); 6247 } 6248 } 6249 } 6250 } 6251 } 6252 6253 final String pkgName = pkg.packageName; 6254 6255 final long scanFileTime = scanFile.lastModified(); 6256 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 6257 pkg.applicationInfo.processName = fixProcessName( 6258 pkg.applicationInfo.packageName, 6259 pkg.applicationInfo.processName, 6260 pkg.applicationInfo.uid); 6261 6262 File dataPath; 6263 if (mPlatformPackage == pkg) { 6264 // The system package is special. 6265 dataPath = new File(Environment.getDataDirectory(), "system"); 6266 6267 pkg.applicationInfo.dataDir = dataPath.getPath(); 6268 6269 } else { 6270 // This is a normal package, need to make its data directory. 6271 dataPath = PackageManager.getDataDirForUser(pkg.volumeUuid, pkg.packageName, 6272 UserHandle.USER_OWNER); 6273 6274 boolean uidError = false; 6275 if (dataPath.exists()) { 6276 int currentUid = 0; 6277 try { 6278 StructStat stat = Os.stat(dataPath.getPath()); 6279 currentUid = stat.st_uid; 6280 } catch (ErrnoException e) { 6281 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 6282 } 6283 6284 // If we have mismatched owners for the data path, we have a problem. 6285 if (currentUid != pkg.applicationInfo.uid) { 6286 boolean recovered = false; 6287 if (currentUid == 0) { 6288 // The directory somehow became owned by root. Wow. 6289 // This is probably because the system was stopped while 6290 // installd was in the middle of messing with its libs 6291 // directory. Ask installd to fix that. 6292 int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName, 6293 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 6294 if (ret >= 0) { 6295 recovered = true; 6296 String msg = "Package " + pkg.packageName 6297 + " unexpectedly changed to uid 0; recovered to " + 6298 + pkg.applicationInfo.uid; 6299 reportSettingsProblem(Log.WARN, msg); 6300 } 6301 } 6302 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6303 || (scanFlags&SCAN_BOOTING) != 0)) { 6304 // If this is a system app, we can at least delete its 6305 // current data so the application will still work. 6306 int ret = removeDataDirsLI(pkg.volumeUuid, pkgName); 6307 if (ret >= 0) { 6308 // TODO: Kill the processes first 6309 // Old data gone! 6310 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 6311 ? "System package " : "Third party package "; 6312 String msg = prefix + pkg.packageName 6313 + " has changed from uid: " 6314 + currentUid + " to " 6315 + pkg.applicationInfo.uid + "; old data erased"; 6316 reportSettingsProblem(Log.WARN, msg); 6317 recovered = true; 6318 6319 // And now re-install the app. 6320 ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6321 pkg.applicationInfo.seinfo); 6322 if (ret == -1) { 6323 // Ack should not happen! 6324 msg = prefix + pkg.packageName 6325 + " could not have data directory re-created after delete."; 6326 reportSettingsProblem(Log.WARN, msg); 6327 throw new PackageManagerException( 6328 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 6329 } 6330 } 6331 if (!recovered) { 6332 mHasSystemUidErrors = true; 6333 } 6334 } else if (!recovered) { 6335 // If we allow this install to proceed, we will be broken. 6336 // Abort, abort! 6337 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 6338 "scanPackageLI"); 6339 } 6340 if (!recovered) { 6341 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 6342 + pkg.applicationInfo.uid + "/fs_" 6343 + currentUid; 6344 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 6345 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 6346 String msg = "Package " + pkg.packageName 6347 + " has mismatched uid: " 6348 + currentUid + " on disk, " 6349 + pkg.applicationInfo.uid + " in settings"; 6350 // writer 6351 synchronized (mPackages) { 6352 mSettings.mReadMessages.append(msg); 6353 mSettings.mReadMessages.append('\n'); 6354 uidError = true; 6355 if (!pkgSetting.uidError) { 6356 reportSettingsProblem(Log.ERROR, msg); 6357 } 6358 } 6359 } 6360 } 6361 pkg.applicationInfo.dataDir = dataPath.getPath(); 6362 if (mShouldRestoreconData) { 6363 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 6364 mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName, 6365 pkg.applicationInfo.seinfo, pkg.applicationInfo.uid); 6366 } 6367 } else { 6368 if (DEBUG_PACKAGE_SCANNING) { 6369 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6370 Log.v(TAG, "Want this data dir: " + dataPath); 6371 } 6372 //invoke installer to do the actual installation 6373 int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid, 6374 pkg.applicationInfo.seinfo); 6375 if (ret < 0) { 6376 // Error from installer 6377 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 6378 "Unable to create data dirs [errorCode=" + ret + "]"); 6379 } 6380 6381 if (dataPath.exists()) { 6382 pkg.applicationInfo.dataDir = dataPath.getPath(); 6383 } else { 6384 Slog.w(TAG, "Unable to create data directory: " + dataPath); 6385 pkg.applicationInfo.dataDir = null; 6386 } 6387 } 6388 6389 pkgSetting.uidError = uidError; 6390 } 6391 6392 final String path = scanFile.getPath(); 6393 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 6394 6395 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 6396 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 6397 6398 // Some system apps still use directory structure for native libraries 6399 // in which case we might end up not detecting abi solely based on apk 6400 // structure. Try to detect abi based on directory structure. 6401 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 6402 pkg.applicationInfo.primaryCpuAbi == null) { 6403 setBundledAppAbisAndRoots(pkg, pkgSetting); 6404 setNativeLibraryPaths(pkg); 6405 } 6406 6407 } else { 6408 if ((scanFlags & SCAN_MOVE) != 0) { 6409 // We haven't run dex-opt for this move (since we've moved the compiled output too) 6410 // but we already have this packages package info in the PackageSetting. We just 6411 // use that and derive the native library path based on the new codepath. 6412 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 6413 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 6414 } 6415 6416 // Set native library paths again. For moves, the path will be updated based on the 6417 // ABIs we've determined above. For non-moves, the path will be updated based on the 6418 // ABIs we determined during compilation, but the path will depend on the final 6419 // package path (after the rename away from the stage path). 6420 setNativeLibraryPaths(pkg); 6421 } 6422 6423 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 6424 final int[] userIds = sUserManager.getUserIds(); 6425 synchronized (mInstallLock) { 6426 // Create a native library symlink only if we have native libraries 6427 // and if the native libraries are 32 bit libraries. We do not provide 6428 // this symlink for 64 bit libraries. 6429 if (pkg.applicationInfo.primaryCpuAbi != null && 6430 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 6431 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 6432 for (int userId : userIds) { 6433 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 6434 nativeLibPath, userId) < 0) { 6435 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 6436 "Failed linking native library dir (user=" + userId + ")"); 6437 } 6438 } 6439 } 6440 } 6441 6442 // This is a special case for the "system" package, where the ABI is 6443 // dictated by the zygote configuration (and init.rc). We should keep track 6444 // of this ABI so that we can deal with "normal" applications that run under 6445 // the same UID correctly. 6446 if (mPlatformPackage == pkg) { 6447 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 6448 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 6449 } 6450 6451 // If there's a mismatch between the abi-override in the package setting 6452 // and the abiOverride specified for the install. Warn about this because we 6453 // would've already compiled the app without taking the package setting into 6454 // account. 6455 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 6456 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 6457 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 6458 " for package: " + pkg.packageName); 6459 } 6460 } 6461 6462 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 6463 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 6464 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 6465 6466 // Copy the derived override back to the parsed package, so that we can 6467 // update the package settings accordingly. 6468 pkg.cpuAbiOverride = cpuAbiOverride; 6469 6470 if (DEBUG_ABI_SELECTION) { 6471 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 6472 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 6473 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 6474 } 6475 6476 // Push the derived path down into PackageSettings so we know what to 6477 // clean up at uninstall time. 6478 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 6479 6480 if (DEBUG_ABI_SELECTION) { 6481 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 6482 " primary=" + pkg.applicationInfo.primaryCpuAbi + 6483 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 6484 } 6485 6486 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 6487 // We don't do this here during boot because we can do it all 6488 // at once after scanning all existing packages. 6489 // 6490 // We also do this *before* we perform dexopt on this package, so that 6491 // we can avoid redundant dexopts, and also to make sure we've got the 6492 // code and package path correct. 6493 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 6494 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); 6495 } 6496 6497 if ((scanFlags & SCAN_NO_DEX) == 0) { 6498 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, 6499 forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */); 6500 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6501 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 6502 } 6503 } 6504 if (mFactoryTest && pkg.requestedPermissions.contains( 6505 android.Manifest.permission.FACTORY_TEST)) { 6506 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 6507 } 6508 6509 ArrayList<PackageParser.Package> clientLibPkgs = null; 6510 6511 // writer 6512 synchronized (mPackages) { 6513 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6514 // Only system apps can add new shared libraries. 6515 if (pkg.libraryNames != null) { 6516 for (int i=0; i<pkg.libraryNames.size(); i++) { 6517 String name = pkg.libraryNames.get(i); 6518 boolean allowed = false; 6519 if (pkg.isUpdatedSystemApp()) { 6520 // New library entries can only be added through the 6521 // system image. This is important to get rid of a lot 6522 // of nasty edge cases: for example if we allowed a non- 6523 // system update of the app to add a library, then uninstalling 6524 // the update would make the library go away, and assumptions 6525 // we made such as through app install filtering would now 6526 // have allowed apps on the device which aren't compatible 6527 // with it. Better to just have the restriction here, be 6528 // conservative, and create many fewer cases that can negatively 6529 // impact the user experience. 6530 final PackageSetting sysPs = mSettings 6531 .getDisabledSystemPkgLPr(pkg.packageName); 6532 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 6533 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 6534 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 6535 allowed = true; 6536 allowed = true; 6537 break; 6538 } 6539 } 6540 } 6541 } else { 6542 allowed = true; 6543 } 6544 if (allowed) { 6545 if (!mSharedLibraries.containsKey(name)) { 6546 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 6547 } else if (!name.equals(pkg.packageName)) { 6548 Slog.w(TAG, "Package " + pkg.packageName + " library " 6549 + name + " already exists; skipping"); 6550 } 6551 } else { 6552 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 6553 + name + " that is not declared on system image; skipping"); 6554 } 6555 } 6556 if ((scanFlags&SCAN_BOOTING) == 0) { 6557 // If we are not booting, we need to update any applications 6558 // that are clients of our shared library. If we are booting, 6559 // this will all be done once the scan is complete. 6560 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 6561 } 6562 } 6563 } 6564 } 6565 6566 // We also need to dexopt any apps that are dependent on this library. Note that 6567 // if these fail, we should abort the install since installing the library will 6568 // result in some apps being broken. 6569 if (clientLibPkgs != null) { 6570 if ((scanFlags & SCAN_NO_DEX) == 0) { 6571 for (int i = 0; i < clientLibPkgs.size(); i++) { 6572 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6573 int result = mPackageDexOptimizer.performDexOpt(clientPkg, 6574 null /* instruction sets */, forceDex, 6575 (scanFlags & SCAN_DEFER_DEX) != 0, false); 6576 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 6577 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 6578 "scanPackageLI failed to dexopt clientLibPkgs"); 6579 } 6580 } 6581 } 6582 } 6583 6584 // Also need to kill any apps that are dependent on the library. 6585 if (clientLibPkgs != null) { 6586 for (int i=0; i<clientLibPkgs.size(); i++) { 6587 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6588 killApplication(clientPkg.applicationInfo.packageName, 6589 clientPkg.applicationInfo.uid, "update lib"); 6590 } 6591 } 6592 6593 // writer 6594 synchronized (mPackages) { 6595 // We don't expect installation to fail beyond this point 6596 6597 // Add the new setting to mSettings 6598 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 6599 // Add the new setting to mPackages 6600 mPackages.put(pkg.applicationInfo.packageName, pkg); 6601 // Make sure we don't accidentally delete its data. 6602 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 6603 while (iter.hasNext()) { 6604 PackageCleanItem item = iter.next(); 6605 if (pkgName.equals(item.packageName)) { 6606 iter.remove(); 6607 } 6608 } 6609 6610 // Take care of first install / last update times. 6611 if (currentTime != 0) { 6612 if (pkgSetting.firstInstallTime == 0) { 6613 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 6614 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 6615 pkgSetting.lastUpdateTime = currentTime; 6616 } 6617 } else if (pkgSetting.firstInstallTime == 0) { 6618 // We need *something*. Take time time stamp of the file. 6619 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 6620 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 6621 if (scanFileTime != pkgSetting.timeStamp) { 6622 // A package on the system image has changed; consider this 6623 // to be an update. 6624 pkgSetting.lastUpdateTime = scanFileTime; 6625 } 6626 } 6627 6628 // Add the package's KeySets to the global KeySetManagerService 6629 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6630 try { 6631 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys); 6632 if (pkg.mKeySetMapping != null) { 6633 ksms.addDefinedKeySetsToPackageLPw(pkg.packageName, pkg.mKeySetMapping); 6634 if (pkg.mUpgradeKeySets != null) { 6635 ksms.addUpgradeKeySetsToPackageLPw(pkg.packageName, pkg.mUpgradeKeySets); 6636 } 6637 } 6638 } catch (NullPointerException e) { 6639 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 6640 } catch (IllegalArgumentException e) { 6641 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 6642 } 6643 6644 int N = pkg.providers.size(); 6645 StringBuilder r = null; 6646 int i; 6647 for (i=0; i<N; i++) { 6648 PackageParser.Provider p = pkg.providers.get(i); 6649 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 6650 p.info.processName, pkg.applicationInfo.uid); 6651 mProviders.addProvider(p); 6652 p.syncable = p.info.isSyncable; 6653 if (p.info.authority != null) { 6654 String names[] = p.info.authority.split(";"); 6655 p.info.authority = null; 6656 for (int j = 0; j < names.length; j++) { 6657 if (j == 1 && p.syncable) { 6658 // We only want the first authority for a provider to possibly be 6659 // syncable, so if we already added this provider using a different 6660 // authority clear the syncable flag. We copy the provider before 6661 // changing it because the mProviders object contains a reference 6662 // to a provider that we don't want to change. 6663 // Only do this for the second authority since the resulting provider 6664 // object can be the same for all future authorities for this provider. 6665 p = new PackageParser.Provider(p); 6666 p.syncable = false; 6667 } 6668 if (!mProvidersByAuthority.containsKey(names[j])) { 6669 mProvidersByAuthority.put(names[j], p); 6670 if (p.info.authority == null) { 6671 p.info.authority = names[j]; 6672 } else { 6673 p.info.authority = p.info.authority + ";" + names[j]; 6674 } 6675 if (DEBUG_PACKAGE_SCANNING) { 6676 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6677 Log.d(TAG, "Registered content provider: " + names[j] 6678 + ", className = " + p.info.name + ", isSyncable = " 6679 + p.info.isSyncable); 6680 } 6681 } else { 6682 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6683 Slog.w(TAG, "Skipping provider name " + names[j] + 6684 " (in package " + pkg.applicationInfo.packageName + 6685 "): name already used by " 6686 + ((other != null && other.getComponentName() != null) 6687 ? other.getComponentName().getPackageName() : "?")); 6688 } 6689 } 6690 } 6691 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6692 if (r == null) { 6693 r = new StringBuilder(256); 6694 } else { 6695 r.append(' '); 6696 } 6697 r.append(p.info.name); 6698 } 6699 } 6700 if (r != null) { 6701 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 6702 } 6703 6704 N = pkg.services.size(); 6705 r = null; 6706 for (i=0; i<N; i++) { 6707 PackageParser.Service s = pkg.services.get(i); 6708 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 6709 s.info.processName, pkg.applicationInfo.uid); 6710 mServices.addService(s); 6711 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6712 if (r == null) { 6713 r = new StringBuilder(256); 6714 } else { 6715 r.append(' '); 6716 } 6717 r.append(s.info.name); 6718 } 6719 } 6720 if (r != null) { 6721 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 6722 } 6723 6724 N = pkg.receivers.size(); 6725 r = null; 6726 for (i=0; i<N; i++) { 6727 PackageParser.Activity a = pkg.receivers.get(i); 6728 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6729 a.info.processName, pkg.applicationInfo.uid); 6730 mReceivers.addActivity(a, "receiver"); 6731 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6732 if (r == null) { 6733 r = new StringBuilder(256); 6734 } else { 6735 r.append(' '); 6736 } 6737 r.append(a.info.name); 6738 } 6739 } 6740 if (r != null) { 6741 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 6742 } 6743 6744 N = pkg.activities.size(); 6745 r = null; 6746 for (i=0; i<N; i++) { 6747 PackageParser.Activity a = pkg.activities.get(i); 6748 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6749 a.info.processName, pkg.applicationInfo.uid); 6750 mActivities.addActivity(a, "activity"); 6751 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6752 if (r == null) { 6753 r = new StringBuilder(256); 6754 } else { 6755 r.append(' '); 6756 } 6757 r.append(a.info.name); 6758 } 6759 } 6760 if (r != null) { 6761 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 6762 } 6763 6764 N = pkg.permissionGroups.size(); 6765 r = null; 6766 for (i=0; i<N; i++) { 6767 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 6768 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 6769 if (cur == null) { 6770 mPermissionGroups.put(pg.info.name, pg); 6771 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6772 if (r == null) { 6773 r = new StringBuilder(256); 6774 } else { 6775 r.append(' '); 6776 } 6777 r.append(pg.info.name); 6778 } 6779 } else { 6780 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 6781 + pg.info.packageName + " ignored: original from " 6782 + cur.info.packageName); 6783 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6784 if (r == null) { 6785 r = new StringBuilder(256); 6786 } else { 6787 r.append(' '); 6788 } 6789 r.append("DUP:"); 6790 r.append(pg.info.name); 6791 } 6792 } 6793 } 6794 if (r != null) { 6795 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 6796 } 6797 6798 N = pkg.permissions.size(); 6799 r = null; 6800 for (i=0; i<N; i++) { 6801 PackageParser.Permission p = pkg.permissions.get(i); 6802 6803 // Now that permission groups have a special meaning, we ignore permission 6804 // groups for legacy apps to prevent unexpected behavior. In particular, 6805 // permissions for one app being granted to someone just becuase they happen 6806 // to be in a group defined by another app (before this had no implications). 6807 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 6808 p.group = mPermissionGroups.get(p.info.group); 6809 // Warn for a permission in an unknown group. 6810 if (p.info.group != null && p.group == null) { 6811 Slog.w(TAG, "Permission " + p.info.name + " from package " 6812 + p.info.packageName + " in an unknown group " + p.info.group); 6813 } 6814 } 6815 6816 ArrayMap<String, BasePermission> permissionMap = 6817 p.tree ? mSettings.mPermissionTrees 6818 : mSettings.mPermissions; 6819 BasePermission bp = permissionMap.get(p.info.name); 6820 6821 // Allow system apps to redefine non-system permissions 6822 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 6823 final boolean currentOwnerIsSystem = (bp.perm != null 6824 && isSystemApp(bp.perm.owner)); 6825 if (isSystemApp(p.owner)) { 6826 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 6827 // It's a built-in permission and no owner, take ownership now 6828 bp.packageSetting = pkgSetting; 6829 bp.perm = p; 6830 bp.uid = pkg.applicationInfo.uid; 6831 bp.sourcePackage = p.info.packageName; 6832 } else if (!currentOwnerIsSystem) { 6833 String msg = "New decl " + p.owner + " of permission " 6834 + p.info.name + " is system; overriding " + bp.sourcePackage; 6835 reportSettingsProblem(Log.WARN, msg); 6836 bp = null; 6837 } 6838 } 6839 } 6840 6841 if (bp == null) { 6842 bp = new BasePermission(p.info.name, p.info.packageName, 6843 BasePermission.TYPE_NORMAL); 6844 permissionMap.put(p.info.name, bp); 6845 } 6846 6847 if (bp.perm == null) { 6848 if (bp.sourcePackage == null 6849 || bp.sourcePackage.equals(p.info.packageName)) { 6850 BasePermission tree = findPermissionTreeLP(p.info.name); 6851 if (tree == null 6852 || tree.sourcePackage.equals(p.info.packageName)) { 6853 bp.packageSetting = pkgSetting; 6854 bp.perm = p; 6855 bp.uid = pkg.applicationInfo.uid; 6856 bp.sourcePackage = p.info.packageName; 6857 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6858 if (r == null) { 6859 r = new StringBuilder(256); 6860 } else { 6861 r.append(' '); 6862 } 6863 r.append(p.info.name); 6864 } 6865 } else { 6866 Slog.w(TAG, "Permission " + p.info.name + " from package " 6867 + p.info.packageName + " ignored: base tree " 6868 + tree.name + " is from package " 6869 + tree.sourcePackage); 6870 } 6871 } else { 6872 Slog.w(TAG, "Permission " + p.info.name + " from package " 6873 + p.info.packageName + " ignored: original from " 6874 + bp.sourcePackage); 6875 } 6876 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6877 if (r == null) { 6878 r = new StringBuilder(256); 6879 } else { 6880 r.append(' '); 6881 } 6882 r.append("DUP:"); 6883 r.append(p.info.name); 6884 } 6885 if (bp.perm == p) { 6886 bp.protectionLevel = p.info.protectionLevel; 6887 } 6888 } 6889 6890 if (r != null) { 6891 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 6892 } 6893 6894 N = pkg.instrumentation.size(); 6895 r = null; 6896 for (i=0; i<N; i++) { 6897 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6898 a.info.packageName = pkg.applicationInfo.packageName; 6899 a.info.sourceDir = pkg.applicationInfo.sourceDir; 6900 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 6901 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 6902 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 6903 a.info.dataDir = pkg.applicationInfo.dataDir; 6904 6905 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 6906 // need other information about the application, like the ABI and what not ? 6907 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 6908 mInstrumentation.put(a.getComponentName(), a); 6909 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6910 if (r == null) { 6911 r = new StringBuilder(256); 6912 } else { 6913 r.append(' '); 6914 } 6915 r.append(a.info.name); 6916 } 6917 } 6918 if (r != null) { 6919 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 6920 } 6921 6922 if (pkg.protectedBroadcasts != null) { 6923 N = pkg.protectedBroadcasts.size(); 6924 for (i=0; i<N; i++) { 6925 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 6926 } 6927 } 6928 6929 pkgSetting.setTimeStamp(scanFileTime); 6930 6931 // Create idmap files for pairs of (packages, overlay packages). 6932 // Note: "android", ie framework-res.apk, is handled by native layers. 6933 if (pkg.mOverlayTarget != null) { 6934 // This is an overlay package. 6935 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 6936 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 6937 mOverlays.put(pkg.mOverlayTarget, 6938 new ArrayMap<String, PackageParser.Package>()); 6939 } 6940 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 6941 map.put(pkg.packageName, pkg); 6942 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 6943 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 6944 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6945 "scanPackageLI failed to createIdmap"); 6946 } 6947 } 6948 } else if (mOverlays.containsKey(pkg.packageName) && 6949 !pkg.packageName.equals("android")) { 6950 // This is a regular package, with one or more known overlay packages. 6951 createIdmapsForPackageLI(pkg); 6952 } 6953 } 6954 6955 return pkg; 6956 } 6957 6958 /** 6959 * Derive the ABI of a non-system package located at {@code scanFile}. This information 6960 * is derived purely on the basis of the contents of {@code scanFile} and 6961 * {@code cpuAbiOverride}. 6962 * 6963 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 6964 */ 6965 public void derivePackageAbi(PackageParser.Package pkg, File scanFile, 6966 String cpuAbiOverride, boolean extractLibs) 6967 throws PackageManagerException { 6968 // TODO: We can probably be smarter about this stuff. For installed apps, 6969 // we can calculate this information at install time once and for all. For 6970 // system apps, we can probably assume that this information doesn't change 6971 // after the first boot scan. As things stand, we do lots of unnecessary work. 6972 6973 // Give ourselves some initial paths; we'll come back for another 6974 // pass once we've determined ABI below. 6975 setNativeLibraryPaths(pkg); 6976 6977 // We would never need to extract libs for forward-locked and external packages, 6978 // since the container service will do it for us. We shouldn't attempt to 6979 // extract libs from system app when it was not updated. 6980 if (pkg.isForwardLocked() || isExternal(pkg) || 6981 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) ) { 6982 extractLibs = false; 6983 } 6984 6985 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 6986 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 6987 6988 NativeLibraryHelper.Handle handle = null; 6989 try { 6990 handle = NativeLibraryHelper.Handle.create(scanFile); 6991 // TODO(multiArch): This can be null for apps that didn't go through the 6992 // usual installation process. We can calculate it again, like we 6993 // do during install time. 6994 // 6995 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 6996 // unnecessary. 6997 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 6998 6999 // Null out the abis so that they can be recalculated. 7000 pkg.applicationInfo.primaryCpuAbi = null; 7001 pkg.applicationInfo.secondaryCpuAbi = null; 7002 if (isMultiArch(pkg.applicationInfo)) { 7003 // Warn if we've set an abiOverride for multi-lib packages.. 7004 // By definition, we need to copy both 32 and 64 bit libraries for 7005 // such packages. 7006 if (pkg.cpuAbiOverride != null 7007 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 7008 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 7009 } 7010 7011 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 7012 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 7013 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 7014 if (extractLibs) { 7015 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7016 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 7017 useIsaSpecificSubdirs); 7018 } else { 7019 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 7020 } 7021 } 7022 7023 maybeThrowExceptionForMultiArchCopy( 7024 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 7025 7026 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 7027 if (extractLibs) { 7028 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7029 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 7030 useIsaSpecificSubdirs); 7031 } else { 7032 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 7033 } 7034 } 7035 7036 maybeThrowExceptionForMultiArchCopy( 7037 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 7038 7039 if (abi64 >= 0) { 7040 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 7041 } 7042 7043 if (abi32 >= 0) { 7044 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 7045 if (abi64 >= 0) { 7046 pkg.applicationInfo.secondaryCpuAbi = abi; 7047 } else { 7048 pkg.applicationInfo.primaryCpuAbi = abi; 7049 } 7050 } 7051 } else { 7052 String[] abiList = (cpuAbiOverride != null) ? 7053 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 7054 7055 // Enable gross and lame hacks for apps that are built with old 7056 // SDK tools. We must scan their APKs for renderscript bitcode and 7057 // not launch them if it's present. Don't bother checking on devices 7058 // that don't have 64 bit support. 7059 boolean needsRenderScriptOverride = false; 7060 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 7061 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 7062 abiList = Build.SUPPORTED_32_BIT_ABIS; 7063 needsRenderScriptOverride = true; 7064 } 7065 7066 final int copyRet; 7067 if (extractLibs) { 7068 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 7069 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 7070 } else { 7071 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 7072 } 7073 7074 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 7075 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 7076 "Error unpackaging native libs for app, errorCode=" + copyRet); 7077 } 7078 7079 if (copyRet >= 0) { 7080 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 7081 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 7082 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 7083 } else if (needsRenderScriptOverride) { 7084 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 7085 } 7086 } 7087 } catch (IOException ioe) { 7088 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 7089 } finally { 7090 IoUtils.closeQuietly(handle); 7091 } 7092 7093 // Now that we've calculated the ABIs and determined if it's an internal app, 7094 // we will go ahead and populate the nativeLibraryPath. 7095 setNativeLibraryPaths(pkg); 7096 } 7097 7098 /** 7099 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 7100 * i.e, so that all packages can be run inside a single process if required. 7101 * 7102 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 7103 * this function will either try and make the ABI for all packages in {@code packagesForUser} 7104 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 7105 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 7106 * updating a package that belongs to a shared user. 7107 * 7108 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 7109 * adds unnecessary complexity. 7110 */ 7111 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 7112 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { 7113 String requiredInstructionSet = null; 7114 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 7115 requiredInstructionSet = VMRuntime.getInstructionSet( 7116 scannedPackage.applicationInfo.primaryCpuAbi); 7117 } 7118 7119 PackageSetting requirer = null; 7120 for (PackageSetting ps : packagesForUser) { 7121 // If packagesForUser contains scannedPackage, we skip it. This will happen 7122 // when scannedPackage is an update of an existing package. Without this check, 7123 // we will never be able to change the ABI of any package belonging to a shared 7124 // user, even if it's compatible with other packages. 7125 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7126 if (ps.primaryCpuAbiString == null) { 7127 continue; 7128 } 7129 7130 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 7131 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 7132 // We have a mismatch between instruction sets (say arm vs arm64) warn about 7133 // this but there's not much we can do. 7134 String errorMessage = "Instruction set mismatch, " 7135 + ((requirer == null) ? "[caller]" : requirer) 7136 + " requires " + requiredInstructionSet + " whereas " + ps 7137 + " requires " + instructionSet; 7138 Slog.w(TAG, errorMessage); 7139 } 7140 7141 if (requiredInstructionSet == null) { 7142 requiredInstructionSet = instructionSet; 7143 requirer = ps; 7144 } 7145 } 7146 } 7147 7148 if (requiredInstructionSet != null) { 7149 String adjustedAbi; 7150 if (requirer != null) { 7151 // requirer != null implies that either scannedPackage was null or that scannedPackage 7152 // did not require an ABI, in which case we have to adjust scannedPackage to match 7153 // the ABI of the set (which is the same as requirer's ABI) 7154 adjustedAbi = requirer.primaryCpuAbiString; 7155 if (scannedPackage != null) { 7156 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 7157 } 7158 } else { 7159 // requirer == null implies that we're updating all ABIs in the set to 7160 // match scannedPackage. 7161 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 7162 } 7163 7164 for (PackageSetting ps : packagesForUser) { 7165 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 7166 if (ps.primaryCpuAbiString != null) { 7167 continue; 7168 } 7169 7170 ps.primaryCpuAbiString = adjustedAbi; 7171 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 7172 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 7173 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 7174 7175 int result = mPackageDexOptimizer.performDexOpt(ps.pkg, 7176 null /* instruction sets */, forceDexOpt, deferDexOpt, true); 7177 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 7178 ps.primaryCpuAbiString = null; 7179 ps.pkg.applicationInfo.primaryCpuAbi = null; 7180 return; 7181 } else { 7182 mInstaller.rmdex(ps.codePathString, 7183 getDexCodeInstructionSet(getPreferredInstructionSet())); 7184 } 7185 } 7186 } 7187 } 7188 } 7189 } 7190 7191 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 7192 synchronized (mPackages) { 7193 mResolverReplaced = true; 7194 // Set up information for custom user intent resolution activity. 7195 mResolveActivity.applicationInfo = pkg.applicationInfo; 7196 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 7197 mResolveActivity.packageName = pkg.applicationInfo.packageName; 7198 mResolveActivity.processName = pkg.applicationInfo.packageName; 7199 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7200 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 7201 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 7202 mResolveActivity.theme = 0; 7203 mResolveActivity.exported = true; 7204 mResolveActivity.enabled = true; 7205 mResolveInfo.activityInfo = mResolveActivity; 7206 mResolveInfo.priority = 0; 7207 mResolveInfo.preferredOrder = 0; 7208 mResolveInfo.match = 0; 7209 mResolveComponentName = mCustomResolverComponentName; 7210 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 7211 mResolveComponentName); 7212 } 7213 } 7214 7215 private static String calculateBundledApkRoot(final String codePathString) { 7216 final File codePath = new File(codePathString); 7217 final File codeRoot; 7218 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 7219 codeRoot = Environment.getRootDirectory(); 7220 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 7221 codeRoot = Environment.getOemDirectory(); 7222 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 7223 codeRoot = Environment.getVendorDirectory(); 7224 } else { 7225 // Unrecognized code path; take its top real segment as the apk root: 7226 // e.g. /something/app/blah.apk => /something 7227 try { 7228 File f = codePath.getCanonicalFile(); 7229 File parent = f.getParentFile(); // non-null because codePath is a file 7230 File tmp; 7231 while ((tmp = parent.getParentFile()) != null) { 7232 f = parent; 7233 parent = tmp; 7234 } 7235 codeRoot = f; 7236 Slog.w(TAG, "Unrecognized code path " 7237 + codePath + " - using " + codeRoot); 7238 } catch (IOException e) { 7239 // Can't canonicalize the code path -- shenanigans? 7240 Slog.w(TAG, "Can't canonicalize code path " + codePath); 7241 return Environment.getRootDirectory().getPath(); 7242 } 7243 } 7244 return codeRoot.getPath(); 7245 } 7246 7247 /** 7248 * Derive and set the location of native libraries for the given package, 7249 * which varies depending on where and how the package was installed. 7250 */ 7251 private void setNativeLibraryPaths(PackageParser.Package pkg) { 7252 final ApplicationInfo info = pkg.applicationInfo; 7253 final String codePath = pkg.codePath; 7254 final File codeFile = new File(codePath); 7255 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 7256 final boolean asecApp = info.isForwardLocked() || isExternal(info); 7257 7258 info.nativeLibraryRootDir = null; 7259 info.nativeLibraryRootRequiresIsa = false; 7260 info.nativeLibraryDir = null; 7261 info.secondaryNativeLibraryDir = null; 7262 7263 if (isApkFile(codeFile)) { 7264 // Monolithic install 7265 if (bundledApp) { 7266 // If "/system/lib64/apkname" exists, assume that is the per-package 7267 // native library directory to use; otherwise use "/system/lib/apkname". 7268 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 7269 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 7270 getPrimaryInstructionSet(info)); 7271 7272 // This is a bundled system app so choose the path based on the ABI. 7273 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 7274 // is just the default path. 7275 final String apkName = deriveCodePathName(codePath); 7276 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 7277 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 7278 apkName).getAbsolutePath(); 7279 7280 if (info.secondaryCpuAbi != null) { 7281 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 7282 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 7283 secondaryLibDir, apkName).getAbsolutePath(); 7284 } 7285 } else if (asecApp) { 7286 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 7287 .getAbsolutePath(); 7288 } else { 7289 final String apkName = deriveCodePathName(codePath); 7290 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 7291 .getAbsolutePath(); 7292 } 7293 7294 info.nativeLibraryRootRequiresIsa = false; 7295 info.nativeLibraryDir = info.nativeLibraryRootDir; 7296 } else { 7297 // Cluster install 7298 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 7299 info.nativeLibraryRootRequiresIsa = true; 7300 7301 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 7302 getPrimaryInstructionSet(info)).getAbsolutePath(); 7303 7304 if (info.secondaryCpuAbi != null) { 7305 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 7306 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 7307 } 7308 } 7309 } 7310 7311 /** 7312 * Calculate the abis and roots for a bundled app. These can uniquely 7313 * be determined from the contents of the system partition, i.e whether 7314 * it contains 64 or 32 bit shared libraries etc. We do not validate any 7315 * of this information, and instead assume that the system was built 7316 * sensibly. 7317 */ 7318 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 7319 PackageSetting pkgSetting) { 7320 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 7321 7322 // If "/system/lib64/apkname" exists, assume that is the per-package 7323 // native library directory to use; otherwise use "/system/lib/apkname". 7324 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 7325 setBundledAppAbi(pkg, apkRoot, apkName); 7326 // pkgSetting might be null during rescan following uninstall of updates 7327 // to a bundled app, so accommodate that possibility. The settings in 7328 // that case will be established later from the parsed package. 7329 // 7330 // If the settings aren't null, sync them up with what we've just derived. 7331 // note that apkRoot isn't stored in the package settings. 7332 if (pkgSetting != null) { 7333 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7334 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7335 } 7336 } 7337 7338 /** 7339 * Deduces the ABI of a bundled app and sets the relevant fields on the 7340 * parsed pkg object. 7341 * 7342 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 7343 * under which system libraries are installed. 7344 * @param apkName the name of the installed package. 7345 */ 7346 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 7347 final File codeFile = new File(pkg.codePath); 7348 7349 final boolean has64BitLibs; 7350 final boolean has32BitLibs; 7351 if (isApkFile(codeFile)) { 7352 // Monolithic install 7353 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 7354 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 7355 } else { 7356 // Cluster install 7357 final File rootDir = new File(codeFile, LIB_DIR_NAME); 7358 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 7359 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 7360 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 7361 has64BitLibs = (new File(rootDir, isa)).exists(); 7362 } else { 7363 has64BitLibs = false; 7364 } 7365 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 7366 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 7367 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 7368 has32BitLibs = (new File(rootDir, isa)).exists(); 7369 } else { 7370 has32BitLibs = false; 7371 } 7372 } 7373 7374 if (has64BitLibs && !has32BitLibs) { 7375 // The package has 64 bit libs, but not 32 bit libs. Its primary 7376 // ABI should be 64 bit. We can safely assume here that the bundled 7377 // native libraries correspond to the most preferred ABI in the list. 7378 7379 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7380 pkg.applicationInfo.secondaryCpuAbi = null; 7381 } else if (has32BitLibs && !has64BitLibs) { 7382 // The package has 32 bit libs but not 64 bit libs. Its primary 7383 // ABI should be 32 bit. 7384 7385 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7386 pkg.applicationInfo.secondaryCpuAbi = null; 7387 } else if (has32BitLibs && has64BitLibs) { 7388 // The application has both 64 and 32 bit bundled libraries. We check 7389 // here that the app declares multiArch support, and warn if it doesn't. 7390 // 7391 // We will be lenient here and record both ABIs. The primary will be the 7392 // ABI that's higher on the list, i.e, a device that's configured to prefer 7393 // 64 bit apps will see a 64 bit primary ABI, 7394 7395 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 7396 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 7397 } 7398 7399 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 7400 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7401 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7402 } else { 7403 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 7404 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 7405 } 7406 } else { 7407 pkg.applicationInfo.primaryCpuAbi = null; 7408 pkg.applicationInfo.secondaryCpuAbi = null; 7409 } 7410 } 7411 7412 private void killApplication(String pkgName, int appId, String reason) { 7413 // Request the ActivityManager to kill the process(only for existing packages) 7414 // so that we do not end up in a confused state while the user is still using the older 7415 // version of the application while the new one gets installed. 7416 IActivityManager am = ActivityManagerNative.getDefault(); 7417 if (am != null) { 7418 try { 7419 am.killApplicationWithAppId(pkgName, appId, reason); 7420 } catch (RemoteException e) { 7421 } 7422 } 7423 } 7424 7425 void removePackageLI(PackageSetting ps, boolean chatty) { 7426 if (DEBUG_INSTALL) { 7427 if (chatty) 7428 Log.d(TAG, "Removing package " + ps.name); 7429 } 7430 7431 // writer 7432 synchronized (mPackages) { 7433 mPackages.remove(ps.name); 7434 final PackageParser.Package pkg = ps.pkg; 7435 if (pkg != null) { 7436 cleanPackageDataStructuresLILPw(pkg, chatty); 7437 } 7438 } 7439 } 7440 7441 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 7442 if (DEBUG_INSTALL) { 7443 if (chatty) 7444 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 7445 } 7446 7447 // writer 7448 synchronized (mPackages) { 7449 mPackages.remove(pkg.applicationInfo.packageName); 7450 cleanPackageDataStructuresLILPw(pkg, chatty); 7451 } 7452 } 7453 7454 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 7455 int N = pkg.providers.size(); 7456 StringBuilder r = null; 7457 int i; 7458 for (i=0; i<N; i++) { 7459 PackageParser.Provider p = pkg.providers.get(i); 7460 mProviders.removeProvider(p); 7461 if (p.info.authority == null) { 7462 7463 /* There was another ContentProvider with this authority when 7464 * this app was installed so this authority is null, 7465 * Ignore it as we don't have to unregister the provider. 7466 */ 7467 continue; 7468 } 7469 String names[] = p.info.authority.split(";"); 7470 for (int j = 0; j < names.length; j++) { 7471 if (mProvidersByAuthority.get(names[j]) == p) { 7472 mProvidersByAuthority.remove(names[j]); 7473 if (DEBUG_REMOVE) { 7474 if (chatty) 7475 Log.d(TAG, "Unregistered content provider: " + names[j] 7476 + ", className = " + p.info.name + ", isSyncable = " 7477 + p.info.isSyncable); 7478 } 7479 } 7480 } 7481 if (DEBUG_REMOVE && chatty) { 7482 if (r == null) { 7483 r = new StringBuilder(256); 7484 } else { 7485 r.append(' '); 7486 } 7487 r.append(p.info.name); 7488 } 7489 } 7490 if (r != null) { 7491 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 7492 } 7493 7494 N = pkg.services.size(); 7495 r = null; 7496 for (i=0; i<N; i++) { 7497 PackageParser.Service s = pkg.services.get(i); 7498 mServices.removeService(s); 7499 if (chatty) { 7500 if (r == null) { 7501 r = new StringBuilder(256); 7502 } else { 7503 r.append(' '); 7504 } 7505 r.append(s.info.name); 7506 } 7507 } 7508 if (r != null) { 7509 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 7510 } 7511 7512 N = pkg.receivers.size(); 7513 r = null; 7514 for (i=0; i<N; i++) { 7515 PackageParser.Activity a = pkg.receivers.get(i); 7516 mReceivers.removeActivity(a, "receiver"); 7517 if (DEBUG_REMOVE && chatty) { 7518 if (r == null) { 7519 r = new StringBuilder(256); 7520 } else { 7521 r.append(' '); 7522 } 7523 r.append(a.info.name); 7524 } 7525 } 7526 if (r != null) { 7527 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 7528 } 7529 7530 N = pkg.activities.size(); 7531 r = null; 7532 for (i=0; i<N; i++) { 7533 PackageParser.Activity a = pkg.activities.get(i); 7534 mActivities.removeActivity(a, "activity"); 7535 if (DEBUG_REMOVE && chatty) { 7536 if (r == null) { 7537 r = new StringBuilder(256); 7538 } else { 7539 r.append(' '); 7540 } 7541 r.append(a.info.name); 7542 } 7543 } 7544 if (r != null) { 7545 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 7546 } 7547 7548 N = pkg.permissions.size(); 7549 r = null; 7550 for (i=0; i<N; i++) { 7551 PackageParser.Permission p = pkg.permissions.get(i); 7552 BasePermission bp = mSettings.mPermissions.get(p.info.name); 7553 if (bp == null) { 7554 bp = mSettings.mPermissionTrees.get(p.info.name); 7555 } 7556 if (bp != null && bp.perm == p) { 7557 bp.perm = null; 7558 if (DEBUG_REMOVE && chatty) { 7559 if (r == null) { 7560 r = new StringBuilder(256); 7561 } else { 7562 r.append(' '); 7563 } 7564 r.append(p.info.name); 7565 } 7566 } 7567 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7568 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 7569 if (appOpPerms != null) { 7570 appOpPerms.remove(pkg.packageName); 7571 } 7572 } 7573 } 7574 if (r != null) { 7575 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7576 } 7577 7578 N = pkg.requestedPermissions.size(); 7579 r = null; 7580 for (i=0; i<N; i++) { 7581 String perm = pkg.requestedPermissions.get(i); 7582 BasePermission bp = mSettings.mPermissions.get(perm); 7583 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7584 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 7585 if (appOpPerms != null) { 7586 appOpPerms.remove(pkg.packageName); 7587 if (appOpPerms.isEmpty()) { 7588 mAppOpPermissionPackages.remove(perm); 7589 } 7590 } 7591 } 7592 } 7593 if (r != null) { 7594 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 7595 } 7596 7597 N = pkg.instrumentation.size(); 7598 r = null; 7599 for (i=0; i<N; i++) { 7600 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 7601 mInstrumentation.remove(a.getComponentName()); 7602 if (DEBUG_REMOVE && chatty) { 7603 if (r == null) { 7604 r = new StringBuilder(256); 7605 } else { 7606 r.append(' '); 7607 } 7608 r.append(a.info.name); 7609 } 7610 } 7611 if (r != null) { 7612 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 7613 } 7614 7615 r = null; 7616 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7617 // Only system apps can hold shared libraries. 7618 if (pkg.libraryNames != null) { 7619 for (i=0; i<pkg.libraryNames.size(); i++) { 7620 String name = pkg.libraryNames.get(i); 7621 SharedLibraryEntry cur = mSharedLibraries.get(name); 7622 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 7623 mSharedLibraries.remove(name); 7624 if (DEBUG_REMOVE && chatty) { 7625 if (r == null) { 7626 r = new StringBuilder(256); 7627 } else { 7628 r.append(' '); 7629 } 7630 r.append(name); 7631 } 7632 } 7633 } 7634 } 7635 } 7636 if (r != null) { 7637 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 7638 } 7639 } 7640 7641 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 7642 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 7643 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 7644 return true; 7645 } 7646 } 7647 return false; 7648 } 7649 7650 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 7651 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 7652 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 7653 7654 private void updatePermissionsLPw(String changingPkg, 7655 PackageParser.Package pkgInfo, int flags) { 7656 // Make sure there are no dangling permission trees. 7657 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 7658 while (it.hasNext()) { 7659 final BasePermission bp = it.next(); 7660 if (bp.packageSetting == null) { 7661 // We may not yet have parsed the package, so just see if 7662 // we still know about its settings. 7663 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7664 } 7665 if (bp.packageSetting == null) { 7666 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 7667 + " from package " + bp.sourcePackage); 7668 it.remove(); 7669 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7670 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7671 Slog.i(TAG, "Removing old permission tree: " + bp.name 7672 + " from package " + bp.sourcePackage); 7673 flags |= UPDATE_PERMISSIONS_ALL; 7674 it.remove(); 7675 } 7676 } 7677 } 7678 7679 // Make sure all dynamic permissions have been assigned to a package, 7680 // and make sure there are no dangling permissions. 7681 it = mSettings.mPermissions.values().iterator(); 7682 while (it.hasNext()) { 7683 final BasePermission bp = it.next(); 7684 if (bp.type == BasePermission.TYPE_DYNAMIC) { 7685 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 7686 + bp.name + " pkg=" + bp.sourcePackage 7687 + " info=" + bp.pendingInfo); 7688 if (bp.packageSetting == null && bp.pendingInfo != null) { 7689 final BasePermission tree = findPermissionTreeLP(bp.name); 7690 if (tree != null && tree.perm != null) { 7691 bp.packageSetting = tree.packageSetting; 7692 bp.perm = new PackageParser.Permission(tree.perm.owner, 7693 new PermissionInfo(bp.pendingInfo)); 7694 bp.perm.info.packageName = tree.perm.info.packageName; 7695 bp.perm.info.name = bp.name; 7696 bp.uid = tree.uid; 7697 } 7698 } 7699 } 7700 if (bp.packageSetting == null) { 7701 // We may not yet have parsed the package, so just see if 7702 // we still know about its settings. 7703 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7704 } 7705 if (bp.packageSetting == null) { 7706 Slog.w(TAG, "Removing dangling permission: " + bp.name 7707 + " from package " + bp.sourcePackage); 7708 it.remove(); 7709 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7710 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7711 Slog.i(TAG, "Removing old permission: " + bp.name 7712 + " from package " + bp.sourcePackage); 7713 flags |= UPDATE_PERMISSIONS_ALL; 7714 it.remove(); 7715 } 7716 } 7717 } 7718 7719 // Now update the permissions for all packages, in particular 7720 // replace the granted permissions of the system packages. 7721 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 7722 for (PackageParser.Package pkg : mPackages.values()) { 7723 if (pkg != pkgInfo) { 7724 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0, 7725 changingPkg); 7726 } 7727 } 7728 } 7729 7730 if (pkgInfo != null) { 7731 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg); 7732 } 7733 } 7734 7735 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 7736 String packageOfInterest) { 7737 // IMPORTANT: There are two types of permissions: install and runtime. 7738 // Install time permissions are granted when the app is installed to 7739 // all device users and users added in the future. Runtime permissions 7740 // are granted at runtime explicitly to specific users. Normal and signature 7741 // protected permissions are install time permissions. Dangerous permissions 7742 // are install permissions if the app's target SDK is Lollipop MR1 or older, 7743 // otherwise they are runtime permissions. This function does not manage 7744 // runtime permissions except for the case an app targeting Lollipop MR1 7745 // being upgraded to target a newer SDK, in which case dangerous permissions 7746 // are transformed from install time to runtime ones. 7747 7748 final PackageSetting ps = (PackageSetting) pkg.mExtras; 7749 if (ps == null) { 7750 return; 7751 } 7752 7753 PermissionsState permissionsState = ps.getPermissionsState(); 7754 PermissionsState origPermissions = permissionsState; 7755 7756 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 7757 7758 int[] upgradeUserIds = EMPTY_INT_ARRAY; 7759 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 7760 7761 boolean changedInstallPermission = false; 7762 7763 if (replace) { 7764 ps.installPermissionsFixed = false; 7765 if (!ps.isSharedUser()) { 7766 origPermissions = new PermissionsState(permissionsState); 7767 permissionsState.reset(); 7768 } 7769 } 7770 7771 permissionsState.setGlobalGids(mGlobalGids); 7772 7773 final int N = pkg.requestedPermissions.size(); 7774 for (int i=0; i<N; i++) { 7775 final String name = pkg.requestedPermissions.get(i); 7776 final BasePermission bp = mSettings.mPermissions.get(name); 7777 7778 if (DEBUG_INSTALL) { 7779 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 7780 } 7781 7782 if (bp == null || bp.packageSetting == null) { 7783 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7784 Slog.w(TAG, "Unknown permission " + name 7785 + " in package " + pkg.packageName); 7786 } 7787 continue; 7788 } 7789 7790 final String perm = bp.name; 7791 boolean allowedSig = false; 7792 int grant = GRANT_DENIED; 7793 7794 // Keep track of app op permissions. 7795 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7796 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 7797 if (pkgs == null) { 7798 pkgs = new ArraySet<>(); 7799 mAppOpPermissionPackages.put(bp.name, pkgs); 7800 } 7801 pkgs.add(pkg.packageName); 7802 } 7803 7804 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 7805 switch (level) { 7806 case PermissionInfo.PROTECTION_NORMAL: { 7807 // For all apps normal permissions are install time ones. 7808 grant = GRANT_INSTALL; 7809 } break; 7810 7811 case PermissionInfo.PROTECTION_DANGEROUS: { 7812 if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) { 7813 // For legacy apps dangerous permissions are install time ones. 7814 grant = GRANT_INSTALL_LEGACY; 7815 } else if (ps.isSystem()) { 7816 final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds(); 7817 if (origPermissions.hasInstallPermission(bp.name)) { 7818 // If a system app had an install permission, then the app was 7819 // upgraded and we grant the permissions as runtime to all users. 7820 grant = GRANT_UPGRADE; 7821 upgradeUserIds = currentUserIds; 7822 } else if (!Arrays.equals(updatedUserIds, currentUserIds)) { 7823 // If users changed since the last permissions update for a 7824 // system app, we grant the permission as runtime to the new users. 7825 grant = GRANT_UPGRADE; 7826 upgradeUserIds = currentUserIds; 7827 for (int userId : updatedUserIds) { 7828 upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId); 7829 } 7830 } else { 7831 // Otherwise, we grant the permission as runtime if the app 7832 // already had it, i.e. we preserve runtime permissions. 7833 grant = GRANT_RUNTIME; 7834 } 7835 } else if (origPermissions.hasInstallPermission(bp.name)) { 7836 // For legacy apps that became modern, install becomes runtime. 7837 grant = GRANT_UPGRADE; 7838 upgradeUserIds = currentUserIds; 7839 } else if (replace) { 7840 // For upgraded modern apps keep runtime permissions unchanged. 7841 grant = GRANT_RUNTIME; 7842 } 7843 } break; 7844 7845 case PermissionInfo.PROTECTION_SIGNATURE: { 7846 // For all apps signature permissions are install time ones. 7847 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 7848 if (allowedSig) { 7849 grant = GRANT_INSTALL; 7850 } 7851 } break; 7852 } 7853 7854 if (DEBUG_INSTALL) { 7855 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 7856 } 7857 7858 if (grant != GRANT_DENIED) { 7859 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 7860 // If this is an existing, non-system package, then 7861 // we can't add any new permissions to it. 7862 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 7863 // Except... if this is a permission that was added 7864 // to the platform (note: need to only do this when 7865 // updating the platform). 7866 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 7867 grant = GRANT_DENIED; 7868 } 7869 } 7870 } 7871 7872 switch (grant) { 7873 case GRANT_INSTALL: { 7874 // Revoke this as runtime permission to handle the case of 7875 // a runtime permssion being downgraded to an install one. 7876 for (int userId : UserManagerService.getInstance().getUserIds()) { 7877 if (origPermissions.getRuntimePermissionState( 7878 bp.name, userId) != null) { 7879 // Revoke the runtime permission and clear the flags. 7880 origPermissions.revokeRuntimePermission(bp, userId); 7881 origPermissions.updatePermissionFlags(bp, userId, 7882 PackageManager.MASK_PERMISSION_FLAGS, 0); 7883 // If we revoked a permission permission, we have to write. 7884 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7885 changedRuntimePermissionUserIds, userId); 7886 } 7887 } 7888 // Grant an install permission. 7889 if (permissionsState.grantInstallPermission(bp) != 7890 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7891 changedInstallPermission = true; 7892 } 7893 } break; 7894 7895 case GRANT_INSTALL_LEGACY: { 7896 // Grant an install permission. 7897 if (permissionsState.grantInstallPermission(bp) != 7898 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7899 changedInstallPermission = true; 7900 } 7901 } break; 7902 7903 case GRANT_RUNTIME: { 7904 // Grant previously granted runtime permissions. 7905 for (int userId : UserManagerService.getInstance().getUserIds()) { 7906 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 7907 PermissionState permissionState = origPermissions 7908 .getRuntimePermissionState(bp.name, userId); 7909 final int flags = permissionState.getFlags(); 7910 if (permissionsState.grantRuntimePermission(bp, userId) == 7911 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7912 // If we cannot put the permission as it was, we have to write. 7913 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7914 changedRuntimePermissionUserIds, userId); 7915 } else { 7916 // System components not only get the permissions but 7917 // they are also fixed, so nothing can change that. 7918 final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg) 7919 ? flags 7920 : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 7921 // Propagate the permission flags. 7922 permissionsState.updatePermissionFlags(bp, userId, 7923 newFlags, newFlags); 7924 } 7925 } 7926 } 7927 } break; 7928 7929 case GRANT_UPGRADE: { 7930 // Grant runtime permissions for a previously held install permission. 7931 PermissionState permissionState = origPermissions 7932 .getInstallPermissionState(bp.name); 7933 final int flags = permissionState != null ? permissionState.getFlags() : 0; 7934 7935 origPermissions.revokeInstallPermission(bp); 7936 // We will be transferring the permission flags, so clear them. 7937 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 7938 PackageManager.MASK_PERMISSION_FLAGS, 0); 7939 7940 // If the permission is not to be promoted to runtime we ignore it and 7941 // also its other flags as they are not applicable to install permissions. 7942 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 7943 for (int userId : upgradeUserIds) { 7944 if (permissionsState.grantRuntimePermission(bp, userId) != 7945 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7946 // System components not only get the permissions but 7947 // they are also fixed so nothing can change that. 7948 final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg) 7949 ? flags 7950 : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 7951 // Transfer the permission flags. 7952 permissionsState.updatePermissionFlags(bp, userId, 7953 newFlags, newFlags); 7954 // If we granted the permission, we have to write. 7955 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 7956 changedRuntimePermissionUserIds, userId); 7957 } 7958 } 7959 } 7960 } break; 7961 7962 default: { 7963 if (packageOfInterest == null 7964 || packageOfInterest.equals(pkg.packageName)) { 7965 Slog.w(TAG, "Not granting permission " + perm 7966 + " to package " + pkg.packageName 7967 + " because it was previously installed without"); 7968 } 7969 } break; 7970 } 7971 } else { 7972 if (permissionsState.revokeInstallPermission(bp) != 7973 PermissionsState.PERMISSION_OPERATION_FAILURE) { 7974 // Also drop the permission flags. 7975 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 7976 PackageManager.MASK_PERMISSION_FLAGS, 0); 7977 changedInstallPermission = true; 7978 Slog.i(TAG, "Un-granting permission " + perm 7979 + " from package " + pkg.packageName 7980 + " (protectionLevel=" + bp.protectionLevel 7981 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7982 + ")"); 7983 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 7984 // Don't print warning for app op permissions, since it is fine for them 7985 // not to be granted, there is a UI for the user to decide. 7986 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7987 Slog.w(TAG, "Not granting permission " + perm 7988 + " to package " + pkg.packageName 7989 + " (protectionLevel=" + bp.protectionLevel 7990 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7991 + ")"); 7992 } 7993 } 7994 } 7995 } 7996 7997 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 7998 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 7999 // This is the first that we have heard about this package, so the 8000 // permissions we have now selected are fixed until explicitly 8001 // changed. 8002 ps.installPermissionsFixed = true; 8003 } 8004 8005 ps.setPermissionsUpdatedForUserIds(currentUserIds); 8006 8007 // Persist the runtime permissions state for users with changes. 8008 for (int userId : changedRuntimePermissionUserIds) { 8009 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 8010 } 8011 } 8012 8013 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 8014 boolean allowed = false; 8015 final int NP = PackageParser.NEW_PERMISSIONS.length; 8016 for (int ip=0; ip<NP; ip++) { 8017 final PackageParser.NewPermissionInfo npi 8018 = PackageParser.NEW_PERMISSIONS[ip]; 8019 if (npi.name.equals(perm) 8020 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 8021 allowed = true; 8022 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 8023 + pkg.packageName); 8024 break; 8025 } 8026 } 8027 return allowed; 8028 } 8029 8030 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 8031 BasePermission bp, PermissionsState origPermissions) { 8032 boolean allowed; 8033 allowed = (compareSignatures( 8034 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 8035 == PackageManager.SIGNATURE_MATCH) 8036 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 8037 == PackageManager.SIGNATURE_MATCH); 8038 if (!allowed && (bp.protectionLevel 8039 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 8040 if (isSystemApp(pkg)) { 8041 // For updated system applications, a system permission 8042 // is granted only if it had been defined by the original application. 8043 if (pkg.isUpdatedSystemApp()) { 8044 final PackageSetting sysPs = mSettings 8045 .getDisabledSystemPkgLPr(pkg.packageName); 8046 if (sysPs.getPermissionsState().hasInstallPermission(perm)) { 8047 // If the original was granted this permission, we take 8048 // that grant decision as read and propagate it to the 8049 // update. 8050 if (sysPs.isPrivileged()) { 8051 allowed = true; 8052 } 8053 } else { 8054 // The system apk may have been updated with an older 8055 // version of the one on the data partition, but which 8056 // granted a new system permission that it didn't have 8057 // before. In this case we do want to allow the app to 8058 // now get the new permission if the ancestral apk is 8059 // privileged to get it. 8060 if (sysPs.pkg != null && sysPs.isPrivileged()) { 8061 for (int j=0; 8062 j<sysPs.pkg.requestedPermissions.size(); j++) { 8063 if (perm.equals( 8064 sysPs.pkg.requestedPermissions.get(j))) { 8065 allowed = true; 8066 break; 8067 } 8068 } 8069 } 8070 } 8071 } else { 8072 allowed = isPrivilegedApp(pkg); 8073 } 8074 } 8075 } 8076 if (!allowed && (bp.protectionLevel 8077 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 8078 // For development permissions, a development permission 8079 // is granted only if it was already granted. 8080 allowed = origPermissions.hasInstallPermission(perm); 8081 } 8082 return allowed; 8083 } 8084 8085 final class ActivityIntentResolver 8086 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 8087 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8088 boolean defaultOnly, int userId) { 8089 if (!sUserManager.exists(userId)) return null; 8090 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8091 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8092 } 8093 8094 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8095 int userId) { 8096 if (!sUserManager.exists(userId)) return null; 8097 mFlags = flags; 8098 return super.queryIntent(intent, resolvedType, 8099 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8100 } 8101 8102 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8103 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 8104 if (!sUserManager.exists(userId)) return null; 8105 if (packageActivities == null) { 8106 return null; 8107 } 8108 mFlags = flags; 8109 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8110 final int N = packageActivities.size(); 8111 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 8112 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 8113 8114 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 8115 for (int i = 0; i < N; ++i) { 8116 intentFilters = packageActivities.get(i).intents; 8117 if (intentFilters != null && intentFilters.size() > 0) { 8118 PackageParser.ActivityIntentInfo[] array = 8119 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 8120 intentFilters.toArray(array); 8121 listCut.add(array); 8122 } 8123 } 8124 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8125 } 8126 8127 public final void addActivity(PackageParser.Activity a, String type) { 8128 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 8129 mActivities.put(a.getComponentName(), a); 8130 if (DEBUG_SHOW_INFO) 8131 Log.v( 8132 TAG, " " + type + " " + 8133 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 8134 if (DEBUG_SHOW_INFO) 8135 Log.v(TAG, " Class=" + a.info.name); 8136 final int NI = a.intents.size(); 8137 for (int j=0; j<NI; j++) { 8138 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 8139 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 8140 intent.setPriority(0); 8141 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 8142 + a.className + " with priority > 0, forcing to 0"); 8143 } 8144 if (DEBUG_SHOW_INFO) { 8145 Log.v(TAG, " IntentFilter:"); 8146 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8147 } 8148 if (!intent.debugCheck()) { 8149 Log.w(TAG, "==> For Activity " + a.info.name); 8150 } 8151 addFilter(intent); 8152 } 8153 } 8154 8155 public final void removeActivity(PackageParser.Activity a, String type) { 8156 mActivities.remove(a.getComponentName()); 8157 if (DEBUG_SHOW_INFO) { 8158 Log.v(TAG, " " + type + " " 8159 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 8160 : a.info.name) + ":"); 8161 Log.v(TAG, " Class=" + a.info.name); 8162 } 8163 final int NI = a.intents.size(); 8164 for (int j=0; j<NI; j++) { 8165 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 8166 if (DEBUG_SHOW_INFO) { 8167 Log.v(TAG, " IntentFilter:"); 8168 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8169 } 8170 removeFilter(intent); 8171 } 8172 } 8173 8174 @Override 8175 protected boolean allowFilterResult( 8176 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 8177 ActivityInfo filterAi = filter.activity.info; 8178 for (int i=dest.size()-1; i>=0; i--) { 8179 ActivityInfo destAi = dest.get(i).activityInfo; 8180 if (destAi.name == filterAi.name 8181 && destAi.packageName == filterAi.packageName) { 8182 return false; 8183 } 8184 } 8185 return true; 8186 } 8187 8188 @Override 8189 protected ActivityIntentInfo[] newArray(int size) { 8190 return new ActivityIntentInfo[size]; 8191 } 8192 8193 @Override 8194 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 8195 if (!sUserManager.exists(userId)) return true; 8196 PackageParser.Package p = filter.activity.owner; 8197 if (p != null) { 8198 PackageSetting ps = (PackageSetting)p.mExtras; 8199 if (ps != null) { 8200 // System apps are never considered stopped for purposes of 8201 // filtering, because there may be no way for the user to 8202 // actually re-launch them. 8203 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 8204 && ps.getStopped(userId); 8205 } 8206 } 8207 return false; 8208 } 8209 8210 @Override 8211 protected boolean isPackageForFilter(String packageName, 8212 PackageParser.ActivityIntentInfo info) { 8213 return packageName.equals(info.activity.owner.packageName); 8214 } 8215 8216 @Override 8217 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 8218 int match, int userId) { 8219 if (!sUserManager.exists(userId)) return null; 8220 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 8221 return null; 8222 } 8223 final PackageParser.Activity activity = info.activity; 8224 if (mSafeMode && (activity.info.applicationInfo.flags 8225 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8226 return null; 8227 } 8228 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 8229 if (ps == null) { 8230 return null; 8231 } 8232 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 8233 ps.readUserState(userId), userId); 8234 if (ai == null) { 8235 return null; 8236 } 8237 final ResolveInfo res = new ResolveInfo(); 8238 res.activityInfo = ai; 8239 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 8240 res.filter = info; 8241 } 8242 if (info != null) { 8243 res.handleAllWebDataURI = info.handleAllWebDataURI(); 8244 } 8245 res.priority = info.getPriority(); 8246 res.preferredOrder = activity.owner.mPreferredOrder; 8247 //System.out.println("Result: " + res.activityInfo.className + 8248 // " = " + res.priority); 8249 res.match = match; 8250 res.isDefault = info.hasDefault; 8251 res.labelRes = info.labelRes; 8252 res.nonLocalizedLabel = info.nonLocalizedLabel; 8253 if (userNeedsBadging(userId)) { 8254 res.noResourceId = true; 8255 } else { 8256 res.icon = info.icon; 8257 } 8258 res.system = res.activityInfo.applicationInfo.isSystemApp(); 8259 return res; 8260 } 8261 8262 @Override 8263 protected void sortResults(List<ResolveInfo> results) { 8264 Collections.sort(results, mResolvePrioritySorter); 8265 } 8266 8267 @Override 8268 protected void dumpFilter(PrintWriter out, String prefix, 8269 PackageParser.ActivityIntentInfo filter) { 8270 out.print(prefix); out.print( 8271 Integer.toHexString(System.identityHashCode(filter.activity))); 8272 out.print(' '); 8273 filter.activity.printComponentShortName(out); 8274 out.print(" filter "); 8275 out.println(Integer.toHexString(System.identityHashCode(filter))); 8276 } 8277 8278 @Override 8279 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 8280 return filter.activity; 8281 } 8282 8283 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8284 PackageParser.Activity activity = (PackageParser.Activity)label; 8285 out.print(prefix); out.print( 8286 Integer.toHexString(System.identityHashCode(activity))); 8287 out.print(' '); 8288 activity.printComponentShortName(out); 8289 if (count > 1) { 8290 out.print(" ("); out.print(count); out.print(" filters)"); 8291 } 8292 out.println(); 8293 } 8294 8295// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8296// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8297// final List<ResolveInfo> retList = Lists.newArrayList(); 8298// while (i.hasNext()) { 8299// final ResolveInfo resolveInfo = i.next(); 8300// if (isEnabledLP(resolveInfo.activityInfo)) { 8301// retList.add(resolveInfo); 8302// } 8303// } 8304// return retList; 8305// } 8306 8307 // Keys are String (activity class name), values are Activity. 8308 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 8309 = new ArrayMap<ComponentName, PackageParser.Activity>(); 8310 private int mFlags; 8311 } 8312 8313 private final class ServiceIntentResolver 8314 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 8315 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8316 boolean defaultOnly, int userId) { 8317 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8318 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8319 } 8320 8321 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8322 int userId) { 8323 if (!sUserManager.exists(userId)) return null; 8324 mFlags = flags; 8325 return super.queryIntent(intent, resolvedType, 8326 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8327 } 8328 8329 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8330 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 8331 if (!sUserManager.exists(userId)) return null; 8332 if (packageServices == null) { 8333 return null; 8334 } 8335 mFlags = flags; 8336 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 8337 final int N = packageServices.size(); 8338 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 8339 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 8340 8341 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 8342 for (int i = 0; i < N; ++i) { 8343 intentFilters = packageServices.get(i).intents; 8344 if (intentFilters != null && intentFilters.size() > 0) { 8345 PackageParser.ServiceIntentInfo[] array = 8346 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 8347 intentFilters.toArray(array); 8348 listCut.add(array); 8349 } 8350 } 8351 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8352 } 8353 8354 public final void addService(PackageParser.Service s) { 8355 mServices.put(s.getComponentName(), s); 8356 if (DEBUG_SHOW_INFO) { 8357 Log.v(TAG, " " 8358 + (s.info.nonLocalizedLabel != null 8359 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8360 Log.v(TAG, " Class=" + s.info.name); 8361 } 8362 final int NI = s.intents.size(); 8363 int j; 8364 for (j=0; j<NI; j++) { 8365 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8366 if (DEBUG_SHOW_INFO) { 8367 Log.v(TAG, " IntentFilter:"); 8368 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8369 } 8370 if (!intent.debugCheck()) { 8371 Log.w(TAG, "==> For Service " + s.info.name); 8372 } 8373 addFilter(intent); 8374 } 8375 } 8376 8377 public final void removeService(PackageParser.Service s) { 8378 mServices.remove(s.getComponentName()); 8379 if (DEBUG_SHOW_INFO) { 8380 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 8381 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 8382 Log.v(TAG, " Class=" + s.info.name); 8383 } 8384 final int NI = s.intents.size(); 8385 int j; 8386 for (j=0; j<NI; j++) { 8387 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 8388 if (DEBUG_SHOW_INFO) { 8389 Log.v(TAG, " IntentFilter:"); 8390 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8391 } 8392 removeFilter(intent); 8393 } 8394 } 8395 8396 @Override 8397 protected boolean allowFilterResult( 8398 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 8399 ServiceInfo filterSi = filter.service.info; 8400 for (int i=dest.size()-1; i>=0; i--) { 8401 ServiceInfo destAi = dest.get(i).serviceInfo; 8402 if (destAi.name == filterSi.name 8403 && destAi.packageName == filterSi.packageName) { 8404 return false; 8405 } 8406 } 8407 return true; 8408 } 8409 8410 @Override 8411 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 8412 return new PackageParser.ServiceIntentInfo[size]; 8413 } 8414 8415 @Override 8416 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 8417 if (!sUserManager.exists(userId)) return true; 8418 PackageParser.Package p = filter.service.owner; 8419 if (p != null) { 8420 PackageSetting ps = (PackageSetting)p.mExtras; 8421 if (ps != null) { 8422 // System apps are never considered stopped for purposes of 8423 // filtering, because there may be no way for the user to 8424 // actually re-launch them. 8425 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8426 && ps.getStopped(userId); 8427 } 8428 } 8429 return false; 8430 } 8431 8432 @Override 8433 protected boolean isPackageForFilter(String packageName, 8434 PackageParser.ServiceIntentInfo info) { 8435 return packageName.equals(info.service.owner.packageName); 8436 } 8437 8438 @Override 8439 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 8440 int match, int userId) { 8441 if (!sUserManager.exists(userId)) return null; 8442 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 8443 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 8444 return null; 8445 } 8446 final PackageParser.Service service = info.service; 8447 if (mSafeMode && (service.info.applicationInfo.flags 8448 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8449 return null; 8450 } 8451 PackageSetting ps = (PackageSetting) service.owner.mExtras; 8452 if (ps == null) { 8453 return null; 8454 } 8455 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 8456 ps.readUserState(userId), userId); 8457 if (si == null) { 8458 return null; 8459 } 8460 final ResolveInfo res = new ResolveInfo(); 8461 res.serviceInfo = si; 8462 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 8463 res.filter = filter; 8464 } 8465 res.priority = info.getPriority(); 8466 res.preferredOrder = service.owner.mPreferredOrder; 8467 res.match = match; 8468 res.isDefault = info.hasDefault; 8469 res.labelRes = info.labelRes; 8470 res.nonLocalizedLabel = info.nonLocalizedLabel; 8471 res.icon = info.icon; 8472 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 8473 return res; 8474 } 8475 8476 @Override 8477 protected void sortResults(List<ResolveInfo> results) { 8478 Collections.sort(results, mResolvePrioritySorter); 8479 } 8480 8481 @Override 8482 protected void dumpFilter(PrintWriter out, String prefix, 8483 PackageParser.ServiceIntentInfo filter) { 8484 out.print(prefix); out.print( 8485 Integer.toHexString(System.identityHashCode(filter.service))); 8486 out.print(' '); 8487 filter.service.printComponentShortName(out); 8488 out.print(" filter "); 8489 out.println(Integer.toHexString(System.identityHashCode(filter))); 8490 } 8491 8492 @Override 8493 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 8494 return filter.service; 8495 } 8496 8497 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8498 PackageParser.Service service = (PackageParser.Service)label; 8499 out.print(prefix); out.print( 8500 Integer.toHexString(System.identityHashCode(service))); 8501 out.print(' '); 8502 service.printComponentShortName(out); 8503 if (count > 1) { 8504 out.print(" ("); out.print(count); out.print(" filters)"); 8505 } 8506 out.println(); 8507 } 8508 8509// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 8510// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 8511// final List<ResolveInfo> retList = Lists.newArrayList(); 8512// while (i.hasNext()) { 8513// final ResolveInfo resolveInfo = (ResolveInfo) i; 8514// if (isEnabledLP(resolveInfo.serviceInfo)) { 8515// retList.add(resolveInfo); 8516// } 8517// } 8518// return retList; 8519// } 8520 8521 // Keys are String (activity class name), values are Activity. 8522 private final ArrayMap<ComponentName, PackageParser.Service> mServices 8523 = new ArrayMap<ComponentName, PackageParser.Service>(); 8524 private int mFlags; 8525 }; 8526 8527 private final class ProviderIntentResolver 8528 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 8529 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 8530 boolean defaultOnly, int userId) { 8531 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 8532 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 8533 } 8534 8535 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 8536 int userId) { 8537 if (!sUserManager.exists(userId)) 8538 return null; 8539 mFlags = flags; 8540 return super.queryIntent(intent, resolvedType, 8541 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 8542 } 8543 8544 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 8545 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 8546 if (!sUserManager.exists(userId)) 8547 return null; 8548 if (packageProviders == null) { 8549 return null; 8550 } 8551 mFlags = flags; 8552 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 8553 final int N = packageProviders.size(); 8554 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 8555 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 8556 8557 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 8558 for (int i = 0; i < N; ++i) { 8559 intentFilters = packageProviders.get(i).intents; 8560 if (intentFilters != null && intentFilters.size() > 0) { 8561 PackageParser.ProviderIntentInfo[] array = 8562 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 8563 intentFilters.toArray(array); 8564 listCut.add(array); 8565 } 8566 } 8567 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 8568 } 8569 8570 public final void addProvider(PackageParser.Provider p) { 8571 if (mProviders.containsKey(p.getComponentName())) { 8572 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 8573 return; 8574 } 8575 8576 mProviders.put(p.getComponentName(), p); 8577 if (DEBUG_SHOW_INFO) { 8578 Log.v(TAG, " " 8579 + (p.info.nonLocalizedLabel != null 8580 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8581 Log.v(TAG, " Class=" + p.info.name); 8582 } 8583 final int NI = p.intents.size(); 8584 int j; 8585 for (j = 0; j < NI; j++) { 8586 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8587 if (DEBUG_SHOW_INFO) { 8588 Log.v(TAG, " IntentFilter:"); 8589 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8590 } 8591 if (!intent.debugCheck()) { 8592 Log.w(TAG, "==> For Provider " + p.info.name); 8593 } 8594 addFilter(intent); 8595 } 8596 } 8597 8598 public final void removeProvider(PackageParser.Provider p) { 8599 mProviders.remove(p.getComponentName()); 8600 if (DEBUG_SHOW_INFO) { 8601 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 8602 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 8603 Log.v(TAG, " Class=" + p.info.name); 8604 } 8605 final int NI = p.intents.size(); 8606 int j; 8607 for (j = 0; j < NI; j++) { 8608 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 8609 if (DEBUG_SHOW_INFO) { 8610 Log.v(TAG, " IntentFilter:"); 8611 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 8612 } 8613 removeFilter(intent); 8614 } 8615 } 8616 8617 @Override 8618 protected boolean allowFilterResult( 8619 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 8620 ProviderInfo filterPi = filter.provider.info; 8621 for (int i = dest.size() - 1; i >= 0; i--) { 8622 ProviderInfo destPi = dest.get(i).providerInfo; 8623 if (destPi.name == filterPi.name 8624 && destPi.packageName == filterPi.packageName) { 8625 return false; 8626 } 8627 } 8628 return true; 8629 } 8630 8631 @Override 8632 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 8633 return new PackageParser.ProviderIntentInfo[size]; 8634 } 8635 8636 @Override 8637 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 8638 if (!sUserManager.exists(userId)) 8639 return true; 8640 PackageParser.Package p = filter.provider.owner; 8641 if (p != null) { 8642 PackageSetting ps = (PackageSetting) p.mExtras; 8643 if (ps != null) { 8644 // System apps are never considered stopped for purposes of 8645 // filtering, because there may be no way for the user to 8646 // actually re-launch them. 8647 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 8648 && ps.getStopped(userId); 8649 } 8650 } 8651 return false; 8652 } 8653 8654 @Override 8655 protected boolean isPackageForFilter(String packageName, 8656 PackageParser.ProviderIntentInfo info) { 8657 return packageName.equals(info.provider.owner.packageName); 8658 } 8659 8660 @Override 8661 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 8662 int match, int userId) { 8663 if (!sUserManager.exists(userId)) 8664 return null; 8665 final PackageParser.ProviderIntentInfo info = filter; 8666 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 8667 return null; 8668 } 8669 final PackageParser.Provider provider = info.provider; 8670 if (mSafeMode && (provider.info.applicationInfo.flags 8671 & ApplicationInfo.FLAG_SYSTEM) == 0) { 8672 return null; 8673 } 8674 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 8675 if (ps == null) { 8676 return null; 8677 } 8678 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 8679 ps.readUserState(userId), userId); 8680 if (pi == null) { 8681 return null; 8682 } 8683 final ResolveInfo res = new ResolveInfo(); 8684 res.providerInfo = pi; 8685 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 8686 res.filter = filter; 8687 } 8688 res.priority = info.getPriority(); 8689 res.preferredOrder = provider.owner.mPreferredOrder; 8690 res.match = match; 8691 res.isDefault = info.hasDefault; 8692 res.labelRes = info.labelRes; 8693 res.nonLocalizedLabel = info.nonLocalizedLabel; 8694 res.icon = info.icon; 8695 res.system = res.providerInfo.applicationInfo.isSystemApp(); 8696 return res; 8697 } 8698 8699 @Override 8700 protected void sortResults(List<ResolveInfo> results) { 8701 Collections.sort(results, mResolvePrioritySorter); 8702 } 8703 8704 @Override 8705 protected void dumpFilter(PrintWriter out, String prefix, 8706 PackageParser.ProviderIntentInfo filter) { 8707 out.print(prefix); 8708 out.print( 8709 Integer.toHexString(System.identityHashCode(filter.provider))); 8710 out.print(' '); 8711 filter.provider.printComponentShortName(out); 8712 out.print(" filter "); 8713 out.println(Integer.toHexString(System.identityHashCode(filter))); 8714 } 8715 8716 @Override 8717 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 8718 return filter.provider; 8719 } 8720 8721 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 8722 PackageParser.Provider provider = (PackageParser.Provider)label; 8723 out.print(prefix); out.print( 8724 Integer.toHexString(System.identityHashCode(provider))); 8725 out.print(' '); 8726 provider.printComponentShortName(out); 8727 if (count > 1) { 8728 out.print(" ("); out.print(count); out.print(" filters)"); 8729 } 8730 out.println(); 8731 } 8732 8733 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 8734 = new ArrayMap<ComponentName, PackageParser.Provider>(); 8735 private int mFlags; 8736 }; 8737 8738 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 8739 new Comparator<ResolveInfo>() { 8740 public int compare(ResolveInfo r1, ResolveInfo r2) { 8741 int v1 = r1.priority; 8742 int v2 = r2.priority; 8743 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 8744 if (v1 != v2) { 8745 return (v1 > v2) ? -1 : 1; 8746 } 8747 v1 = r1.preferredOrder; 8748 v2 = r2.preferredOrder; 8749 if (v1 != v2) { 8750 return (v1 > v2) ? -1 : 1; 8751 } 8752 if (r1.isDefault != r2.isDefault) { 8753 return r1.isDefault ? -1 : 1; 8754 } 8755 v1 = r1.match; 8756 v2 = r2.match; 8757 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 8758 if (v1 != v2) { 8759 return (v1 > v2) ? -1 : 1; 8760 } 8761 if (r1.system != r2.system) { 8762 return r1.system ? -1 : 1; 8763 } 8764 return 0; 8765 } 8766 }; 8767 8768 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 8769 new Comparator<ProviderInfo>() { 8770 public int compare(ProviderInfo p1, ProviderInfo p2) { 8771 final int v1 = p1.initOrder; 8772 final int v2 = p2.initOrder; 8773 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 8774 } 8775 }; 8776 8777 final void sendPackageBroadcast(final String action, final String pkg, 8778 final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver, 8779 final int[] userIds) { 8780 mHandler.post(new Runnable() { 8781 @Override 8782 public void run() { 8783 try { 8784 final IActivityManager am = ActivityManagerNative.getDefault(); 8785 if (am == null) return; 8786 final int[] resolvedUserIds; 8787 if (userIds == null) { 8788 resolvedUserIds = am.getRunningUserIds(); 8789 } else { 8790 resolvedUserIds = userIds; 8791 } 8792 for (int id : resolvedUserIds) { 8793 final Intent intent = new Intent(action, 8794 pkg != null ? Uri.fromParts("package", pkg, null) : null); 8795 if (extras != null) { 8796 intent.putExtras(extras); 8797 } 8798 if (targetPkg != null) { 8799 intent.setPackage(targetPkg); 8800 } 8801 // Modify the UID when posting to other users 8802 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 8803 if (uid > 0 && UserHandle.getUserId(uid) != id) { 8804 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 8805 intent.putExtra(Intent.EXTRA_UID, uid); 8806 } 8807 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 8808 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 8809 if (DEBUG_BROADCASTS) { 8810 RuntimeException here = new RuntimeException("here"); 8811 here.fillInStackTrace(); 8812 Slog.d(TAG, "Sending to user " + id + ": " 8813 + intent.toShortString(false, true, false, false) 8814 + " " + intent.getExtras(), here); 8815 } 8816 am.broadcastIntent(null, intent, null, finishedReceiver, 8817 0, null, null, null, android.app.AppOpsManager.OP_NONE, 8818 finishedReceiver != null, false, id); 8819 } 8820 } catch (RemoteException ex) { 8821 } 8822 } 8823 }); 8824 } 8825 8826 /** 8827 * Check if the external storage media is available. This is true if there 8828 * is a mounted external storage medium or if the external storage is 8829 * emulated. 8830 */ 8831 private boolean isExternalMediaAvailable() { 8832 return mMediaMounted || Environment.isExternalStorageEmulated(); 8833 } 8834 8835 @Override 8836 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 8837 // writer 8838 synchronized (mPackages) { 8839 if (!isExternalMediaAvailable()) { 8840 // If the external storage is no longer mounted at this point, 8841 // the caller may not have been able to delete all of this 8842 // packages files and can not delete any more. Bail. 8843 return null; 8844 } 8845 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 8846 if (lastPackage != null) { 8847 pkgs.remove(lastPackage); 8848 } 8849 if (pkgs.size() > 0) { 8850 return pkgs.get(0); 8851 } 8852 } 8853 return null; 8854 } 8855 8856 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 8857 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 8858 userId, andCode ? 1 : 0, packageName); 8859 if (mSystemReady) { 8860 msg.sendToTarget(); 8861 } else { 8862 if (mPostSystemReadyMessages == null) { 8863 mPostSystemReadyMessages = new ArrayList<>(); 8864 } 8865 mPostSystemReadyMessages.add(msg); 8866 } 8867 } 8868 8869 void startCleaningPackages() { 8870 // reader 8871 synchronized (mPackages) { 8872 if (!isExternalMediaAvailable()) { 8873 return; 8874 } 8875 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 8876 return; 8877 } 8878 } 8879 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 8880 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 8881 IActivityManager am = ActivityManagerNative.getDefault(); 8882 if (am != null) { 8883 try { 8884 am.startService(null, intent, null, UserHandle.USER_OWNER); 8885 } catch (RemoteException e) { 8886 } 8887 } 8888 } 8889 8890 @Override 8891 public void installPackage(String originPath, IPackageInstallObserver2 observer, 8892 int installFlags, String installerPackageName, VerificationParams verificationParams, 8893 String packageAbiOverride) { 8894 installPackageAsUser(originPath, observer, installFlags, installerPackageName, 8895 verificationParams, packageAbiOverride, UserHandle.getCallingUserId()); 8896 } 8897 8898 @Override 8899 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 8900 int installFlags, String installerPackageName, VerificationParams verificationParams, 8901 String packageAbiOverride, int userId) { 8902 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 8903 8904 final int callingUid = Binder.getCallingUid(); 8905 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 8906 8907 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8908 try { 8909 if (observer != null) { 8910 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 8911 } 8912 } catch (RemoteException re) { 8913 } 8914 return; 8915 } 8916 8917 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 8918 installFlags |= PackageManager.INSTALL_FROM_ADB; 8919 8920 } else { 8921 // Caller holds INSTALL_PACKAGES permission, so we're less strict 8922 // about installerPackageName. 8923 8924 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 8925 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 8926 } 8927 8928 UserHandle user; 8929 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 8930 user = UserHandle.ALL; 8931 } else { 8932 user = new UserHandle(userId); 8933 } 8934 8935 // Only system components can circumvent runtime permissions when installing. 8936 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 8937 && mContext.checkCallingOrSelfPermission(Manifest.permission 8938 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 8939 throw new SecurityException("You need the " 8940 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 8941 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 8942 } 8943 8944 verificationParams.setInstallerUid(callingUid); 8945 8946 final File originFile = new File(originPath); 8947 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 8948 8949 final Message msg = mHandler.obtainMessage(INIT_COPY); 8950 msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName, 8951 null, verificationParams, user, packageAbiOverride); 8952 mHandler.sendMessage(msg); 8953 } 8954 8955 void installStage(String packageName, File stagedDir, String stagedCid, 8956 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, 8957 String installerPackageName, int installerUid, UserHandle user) { 8958 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 8959 params.referrerUri, installerUid, null); 8960 8961 final OriginInfo origin; 8962 if (stagedDir != null) { 8963 origin = OriginInfo.fromStagedFile(stagedDir); 8964 } else { 8965 origin = OriginInfo.fromStagedContainer(stagedCid); 8966 } 8967 8968 final Message msg = mHandler.obtainMessage(INIT_COPY); 8969 msg.obj = new InstallParams(origin, null, observer, params.installFlags, 8970 installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride); 8971 mHandler.sendMessage(msg); 8972 } 8973 8974 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 8975 Bundle extras = new Bundle(1); 8976 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 8977 8978 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 8979 packageName, extras, null, null, new int[] {userId}); 8980 try { 8981 IActivityManager am = ActivityManagerNative.getDefault(); 8982 final boolean isSystem = 8983 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 8984 if (isSystem && am.isUserRunning(userId, false)) { 8985 // The just-installed/enabled app is bundled on the system, so presumed 8986 // to be able to run automatically without needing an explicit launch. 8987 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 8988 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 8989 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 8990 .setPackage(packageName); 8991 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 8992 android.app.AppOpsManager.OP_NONE, false, false, userId); 8993 } 8994 } catch (RemoteException e) { 8995 // shouldn't happen 8996 Slog.w(TAG, "Unable to bootstrap installed package", e); 8997 } 8998 } 8999 9000 @Override 9001 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 9002 int userId) { 9003 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9004 PackageSetting pkgSetting; 9005 final int uid = Binder.getCallingUid(); 9006 enforceCrossUserPermission(uid, userId, true, true, 9007 "setApplicationHiddenSetting for user " + userId); 9008 9009 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 9010 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 9011 return false; 9012 } 9013 9014 long callingId = Binder.clearCallingIdentity(); 9015 try { 9016 boolean sendAdded = false; 9017 boolean sendRemoved = false; 9018 // writer 9019 synchronized (mPackages) { 9020 pkgSetting = mSettings.mPackages.get(packageName); 9021 if (pkgSetting == null) { 9022 return false; 9023 } 9024 if (pkgSetting.getHidden(userId) != hidden) { 9025 pkgSetting.setHidden(hidden, userId); 9026 mSettings.writePackageRestrictionsLPr(userId); 9027 if (hidden) { 9028 sendRemoved = true; 9029 } else { 9030 sendAdded = true; 9031 } 9032 } 9033 } 9034 if (sendAdded) { 9035 sendPackageAddedForUser(packageName, pkgSetting, userId); 9036 return true; 9037 } 9038 if (sendRemoved) { 9039 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 9040 "hiding pkg"); 9041 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 9042 } 9043 } finally { 9044 Binder.restoreCallingIdentity(callingId); 9045 } 9046 return false; 9047 } 9048 9049 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 9050 int userId) { 9051 final PackageRemovedInfo info = new PackageRemovedInfo(); 9052 info.removedPackage = packageName; 9053 info.removedUsers = new int[] {userId}; 9054 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 9055 info.sendBroadcast(false, false, false); 9056 } 9057 9058 /** 9059 * Returns true if application is not found or there was an error. Otherwise it returns 9060 * the hidden state of the package for the given user. 9061 */ 9062 @Override 9063 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 9064 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 9065 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 9066 false, "getApplicationHidden for user " + userId); 9067 PackageSetting pkgSetting; 9068 long callingId = Binder.clearCallingIdentity(); 9069 try { 9070 // writer 9071 synchronized (mPackages) { 9072 pkgSetting = mSettings.mPackages.get(packageName); 9073 if (pkgSetting == null) { 9074 return true; 9075 } 9076 return pkgSetting.getHidden(userId); 9077 } 9078 } finally { 9079 Binder.restoreCallingIdentity(callingId); 9080 } 9081 } 9082 9083 /** 9084 * @hide 9085 */ 9086 @Override 9087 public int installExistingPackageAsUser(String packageName, int userId) { 9088 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 9089 null); 9090 PackageSetting pkgSetting; 9091 final int uid = Binder.getCallingUid(); 9092 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 9093 + userId); 9094 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 9095 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 9096 } 9097 9098 long callingId = Binder.clearCallingIdentity(); 9099 try { 9100 boolean sendAdded = false; 9101 9102 // writer 9103 synchronized (mPackages) { 9104 pkgSetting = mSettings.mPackages.get(packageName); 9105 if (pkgSetting == null) { 9106 return PackageManager.INSTALL_FAILED_INVALID_URI; 9107 } 9108 if (!pkgSetting.getInstalled(userId)) { 9109 pkgSetting.setInstalled(true, userId); 9110 pkgSetting.setHidden(false, userId); 9111 mSettings.writePackageRestrictionsLPr(userId); 9112 sendAdded = true; 9113 } 9114 } 9115 9116 if (sendAdded) { 9117 sendPackageAddedForUser(packageName, pkgSetting, userId); 9118 } 9119 } finally { 9120 Binder.restoreCallingIdentity(callingId); 9121 } 9122 9123 return PackageManager.INSTALL_SUCCEEDED; 9124 } 9125 9126 boolean isUserRestricted(int userId, String restrictionKey) { 9127 Bundle restrictions = sUserManager.getUserRestrictions(userId); 9128 if (restrictions.getBoolean(restrictionKey, false)) { 9129 Log.w(TAG, "User is restricted: " + restrictionKey); 9130 return true; 9131 } 9132 return false; 9133 } 9134 9135 @Override 9136 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 9137 mContext.enforceCallingOrSelfPermission( 9138 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9139 "Only package verification agents can verify applications"); 9140 9141 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 9142 final PackageVerificationResponse response = new PackageVerificationResponse( 9143 verificationCode, Binder.getCallingUid()); 9144 msg.arg1 = id; 9145 msg.obj = response; 9146 mHandler.sendMessage(msg); 9147 } 9148 9149 @Override 9150 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 9151 long millisecondsToDelay) { 9152 mContext.enforceCallingOrSelfPermission( 9153 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9154 "Only package verification agents can extend verification timeouts"); 9155 9156 final PackageVerificationState state = mPendingVerification.get(id); 9157 final PackageVerificationResponse response = new PackageVerificationResponse( 9158 verificationCodeAtTimeout, Binder.getCallingUid()); 9159 9160 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 9161 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 9162 } 9163 if (millisecondsToDelay < 0) { 9164 millisecondsToDelay = 0; 9165 } 9166 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 9167 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 9168 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 9169 } 9170 9171 if ((state != null) && !state.timeoutExtended()) { 9172 state.extendTimeout(); 9173 9174 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 9175 msg.arg1 = id; 9176 msg.obj = response; 9177 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 9178 } 9179 } 9180 9181 private void broadcastPackageVerified(int verificationId, Uri packageUri, 9182 int verificationCode, UserHandle user) { 9183 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 9184 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 9185 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 9186 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 9187 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 9188 9189 mContext.sendBroadcastAsUser(intent, user, 9190 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 9191 } 9192 9193 private ComponentName matchComponentForVerifier(String packageName, 9194 List<ResolveInfo> receivers) { 9195 ActivityInfo targetReceiver = null; 9196 9197 final int NR = receivers.size(); 9198 for (int i = 0; i < NR; i++) { 9199 final ResolveInfo info = receivers.get(i); 9200 if (info.activityInfo == null) { 9201 continue; 9202 } 9203 9204 if (packageName.equals(info.activityInfo.packageName)) { 9205 targetReceiver = info.activityInfo; 9206 break; 9207 } 9208 } 9209 9210 if (targetReceiver == null) { 9211 return null; 9212 } 9213 9214 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 9215 } 9216 9217 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 9218 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 9219 if (pkgInfo.verifiers.length == 0) { 9220 return null; 9221 } 9222 9223 final int N = pkgInfo.verifiers.length; 9224 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 9225 for (int i = 0; i < N; i++) { 9226 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 9227 9228 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 9229 receivers); 9230 if (comp == null) { 9231 continue; 9232 } 9233 9234 final int verifierUid = getUidForVerifier(verifierInfo); 9235 if (verifierUid == -1) { 9236 continue; 9237 } 9238 9239 if (DEBUG_VERIFY) { 9240 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 9241 + " with the correct signature"); 9242 } 9243 sufficientVerifiers.add(comp); 9244 verificationState.addSufficientVerifier(verifierUid); 9245 } 9246 9247 return sufficientVerifiers; 9248 } 9249 9250 private int getUidForVerifier(VerifierInfo verifierInfo) { 9251 synchronized (mPackages) { 9252 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 9253 if (pkg == null) { 9254 return -1; 9255 } else if (pkg.mSignatures.length != 1) { 9256 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 9257 + " has more than one signature; ignoring"); 9258 return -1; 9259 } 9260 9261 /* 9262 * If the public key of the package's signature does not match 9263 * our expected public key, then this is a different package and 9264 * we should skip. 9265 */ 9266 9267 final byte[] expectedPublicKey; 9268 try { 9269 final Signature verifierSig = pkg.mSignatures[0]; 9270 final PublicKey publicKey = verifierSig.getPublicKey(); 9271 expectedPublicKey = publicKey.getEncoded(); 9272 } catch (CertificateException e) { 9273 return -1; 9274 } 9275 9276 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 9277 9278 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 9279 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 9280 + " does not have the expected public key; ignoring"); 9281 return -1; 9282 } 9283 9284 return pkg.applicationInfo.uid; 9285 } 9286 } 9287 9288 @Override 9289 public void finishPackageInstall(int token) { 9290 enforceSystemOrRoot("Only the system is allowed to finish installs"); 9291 9292 if (DEBUG_INSTALL) { 9293 Slog.v(TAG, "BM finishing package install for " + token); 9294 } 9295 9296 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9297 mHandler.sendMessage(msg); 9298 } 9299 9300 /** 9301 * Get the verification agent timeout. 9302 * 9303 * @return verification timeout in milliseconds 9304 */ 9305 private long getVerificationTimeout() { 9306 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 9307 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 9308 DEFAULT_VERIFICATION_TIMEOUT); 9309 } 9310 9311 /** 9312 * Get the default verification agent response code. 9313 * 9314 * @return default verification response code 9315 */ 9316 private int getDefaultVerificationResponse() { 9317 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9318 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 9319 DEFAULT_VERIFICATION_RESPONSE); 9320 } 9321 9322 /** 9323 * Check whether or not package verification has been enabled. 9324 * 9325 * @return true if verification should be performed 9326 */ 9327 private boolean isVerificationEnabled(int userId, int installFlags) { 9328 if (!DEFAULT_VERIFY_ENABLE) { 9329 return false; 9330 } 9331 9332 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 9333 9334 // Check if installing from ADB 9335 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 9336 // Do not run verification in a test harness environment 9337 if (ActivityManager.isRunningInTestHarness()) { 9338 return false; 9339 } 9340 if (ensureVerifyAppsEnabled) { 9341 return true; 9342 } 9343 // Check if the developer does not want package verification for ADB installs 9344 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9345 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 9346 return false; 9347 } 9348 } 9349 9350 if (ensureVerifyAppsEnabled) { 9351 return true; 9352 } 9353 9354 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9355 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 9356 } 9357 9358 @Override 9359 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 9360 throws RemoteException { 9361 mContext.enforceCallingOrSelfPermission( 9362 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 9363 "Only intentfilter verification agents can verify applications"); 9364 9365 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 9366 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 9367 Binder.getCallingUid(), verificationCode, failedDomains); 9368 msg.arg1 = id; 9369 msg.obj = response; 9370 mHandler.sendMessage(msg); 9371 } 9372 9373 @Override 9374 public int getIntentVerificationStatus(String packageName, int userId) { 9375 synchronized (mPackages) { 9376 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 9377 } 9378 } 9379 9380 @Override 9381 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 9382 boolean result = false; 9383 synchronized (mPackages) { 9384 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 9385 } 9386 if (result) { 9387 scheduleWritePackageRestrictionsLocked(userId); 9388 } 9389 return result; 9390 } 9391 9392 @Override 9393 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 9394 synchronized (mPackages) { 9395 return mSettings.getIntentFilterVerificationsLPr(packageName); 9396 } 9397 } 9398 9399 @Override 9400 public List<IntentFilter> getAllIntentFilters(String packageName) { 9401 if (TextUtils.isEmpty(packageName)) { 9402 return Collections.<IntentFilter>emptyList(); 9403 } 9404 synchronized (mPackages) { 9405 PackageParser.Package pkg = mPackages.get(packageName); 9406 if (pkg == null || pkg.activities == null) { 9407 return Collections.<IntentFilter>emptyList(); 9408 } 9409 final int count = pkg.activities.size(); 9410 ArrayList<IntentFilter> result = new ArrayList<>(); 9411 for (int n=0; n<count; n++) { 9412 PackageParser.Activity activity = pkg.activities.get(n); 9413 if (activity.intents != null || activity.intents.size() > 0) { 9414 result.addAll(activity.intents); 9415 } 9416 } 9417 return result; 9418 } 9419 } 9420 9421 @Override 9422 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 9423 synchronized (mPackages) { 9424 boolean result = mSettings.setDefaultBrowserPackageNameLPr(packageName, userId); 9425 if (packageName != null) { 9426 result |= updateIntentVerificationStatus(packageName, 9427 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 9428 UserHandle.myUserId()); 9429 } 9430 return result; 9431 } 9432 } 9433 9434 @Override 9435 public String getDefaultBrowserPackageName(int userId) { 9436 synchronized (mPackages) { 9437 return mSettings.getDefaultBrowserPackageNameLPw(userId); 9438 } 9439 } 9440 9441 /** 9442 * Get the "allow unknown sources" setting. 9443 * 9444 * @return the current "allow unknown sources" setting 9445 */ 9446 private int getUnknownSourcesSettings() { 9447 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 9448 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 9449 -1); 9450 } 9451 9452 @Override 9453 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 9454 final int uid = Binder.getCallingUid(); 9455 // writer 9456 synchronized (mPackages) { 9457 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 9458 if (targetPackageSetting == null) { 9459 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 9460 } 9461 9462 PackageSetting installerPackageSetting; 9463 if (installerPackageName != null) { 9464 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 9465 if (installerPackageSetting == null) { 9466 throw new IllegalArgumentException("Unknown installer package: " 9467 + installerPackageName); 9468 } 9469 } else { 9470 installerPackageSetting = null; 9471 } 9472 9473 Signature[] callerSignature; 9474 Object obj = mSettings.getUserIdLPr(uid); 9475 if (obj != null) { 9476 if (obj instanceof SharedUserSetting) { 9477 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 9478 } else if (obj instanceof PackageSetting) { 9479 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 9480 } else { 9481 throw new SecurityException("Bad object " + obj + " for uid " + uid); 9482 } 9483 } else { 9484 throw new SecurityException("Unknown calling uid " + uid); 9485 } 9486 9487 // Verify: can't set installerPackageName to a package that is 9488 // not signed with the same cert as the caller. 9489 if (installerPackageSetting != null) { 9490 if (compareSignatures(callerSignature, 9491 installerPackageSetting.signatures.mSignatures) 9492 != PackageManager.SIGNATURE_MATCH) { 9493 throw new SecurityException( 9494 "Caller does not have same cert as new installer package " 9495 + installerPackageName); 9496 } 9497 } 9498 9499 // Verify: if target already has an installer package, it must 9500 // be signed with the same cert as the caller. 9501 if (targetPackageSetting.installerPackageName != null) { 9502 PackageSetting setting = mSettings.mPackages.get( 9503 targetPackageSetting.installerPackageName); 9504 // If the currently set package isn't valid, then it's always 9505 // okay to change it. 9506 if (setting != null) { 9507 if (compareSignatures(callerSignature, 9508 setting.signatures.mSignatures) 9509 != PackageManager.SIGNATURE_MATCH) { 9510 throw new SecurityException( 9511 "Caller does not have same cert as old installer package " 9512 + targetPackageSetting.installerPackageName); 9513 } 9514 } 9515 } 9516 9517 // Okay! 9518 targetPackageSetting.installerPackageName = installerPackageName; 9519 scheduleWriteSettingsLocked(); 9520 } 9521 } 9522 9523 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 9524 // Queue up an async operation since the package installation may take a little while. 9525 mHandler.post(new Runnable() { 9526 public void run() { 9527 mHandler.removeCallbacks(this); 9528 // Result object to be returned 9529 PackageInstalledInfo res = new PackageInstalledInfo(); 9530 res.returnCode = currentStatus; 9531 res.uid = -1; 9532 res.pkg = null; 9533 res.removedInfo = new PackageRemovedInfo(); 9534 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 9535 args.doPreInstall(res.returnCode); 9536 synchronized (mInstallLock) { 9537 installPackageLI(args, res); 9538 } 9539 args.doPostInstall(res.returnCode, res.uid); 9540 } 9541 9542 // A restore should be performed at this point if (a) the install 9543 // succeeded, (b) the operation is not an update, and (c) the new 9544 // package has not opted out of backup participation. 9545 final boolean update = res.removedInfo.removedPackage != null; 9546 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 9547 boolean doRestore = !update 9548 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 9549 9550 // Set up the post-install work request bookkeeping. This will be used 9551 // and cleaned up by the post-install event handling regardless of whether 9552 // there's a restore pass performed. Token values are >= 1. 9553 int token; 9554 if (mNextInstallToken < 0) mNextInstallToken = 1; 9555 token = mNextInstallToken++; 9556 9557 PostInstallData data = new PostInstallData(args, res); 9558 mRunningInstalls.put(token, data); 9559 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 9560 9561 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 9562 // Pass responsibility to the Backup Manager. It will perform a 9563 // restore if appropriate, then pass responsibility back to the 9564 // Package Manager to run the post-install observer callbacks 9565 // and broadcasts. 9566 IBackupManager bm = IBackupManager.Stub.asInterface( 9567 ServiceManager.getService(Context.BACKUP_SERVICE)); 9568 if (bm != null) { 9569 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 9570 + " to BM for possible restore"); 9571 try { 9572 if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { 9573 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 9574 } else { 9575 doRestore = false; 9576 } 9577 } catch (RemoteException e) { 9578 // can't happen; the backup manager is local 9579 } catch (Exception e) { 9580 Slog.e(TAG, "Exception trying to enqueue restore", e); 9581 doRestore = false; 9582 } 9583 } else { 9584 Slog.e(TAG, "Backup Manager not found!"); 9585 doRestore = false; 9586 } 9587 } 9588 9589 if (!doRestore) { 9590 // No restore possible, or the Backup Manager was mysteriously not 9591 // available -- just fire the post-install work request directly. 9592 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 9593 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 9594 mHandler.sendMessage(msg); 9595 } 9596 } 9597 }); 9598 } 9599 9600 private abstract class HandlerParams { 9601 private static final int MAX_RETRIES = 4; 9602 9603 /** 9604 * Number of times startCopy() has been attempted and had a non-fatal 9605 * error. 9606 */ 9607 private int mRetries = 0; 9608 9609 /** User handle for the user requesting the information or installation. */ 9610 private final UserHandle mUser; 9611 9612 HandlerParams(UserHandle user) { 9613 mUser = user; 9614 } 9615 9616 UserHandle getUser() { 9617 return mUser; 9618 } 9619 9620 final boolean startCopy() { 9621 boolean res; 9622 try { 9623 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 9624 9625 if (++mRetries > MAX_RETRIES) { 9626 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 9627 mHandler.sendEmptyMessage(MCS_GIVE_UP); 9628 handleServiceError(); 9629 return false; 9630 } else { 9631 handleStartCopy(); 9632 res = true; 9633 } 9634 } catch (RemoteException e) { 9635 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 9636 mHandler.sendEmptyMessage(MCS_RECONNECT); 9637 res = false; 9638 } 9639 handleReturnCode(); 9640 return res; 9641 } 9642 9643 final void serviceError() { 9644 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 9645 handleServiceError(); 9646 handleReturnCode(); 9647 } 9648 9649 abstract void handleStartCopy() throws RemoteException; 9650 abstract void handleServiceError(); 9651 abstract void handleReturnCode(); 9652 } 9653 9654 class MeasureParams extends HandlerParams { 9655 private final PackageStats mStats; 9656 private boolean mSuccess; 9657 9658 private final IPackageStatsObserver mObserver; 9659 9660 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 9661 super(new UserHandle(stats.userHandle)); 9662 mObserver = observer; 9663 mStats = stats; 9664 } 9665 9666 @Override 9667 public String toString() { 9668 return "MeasureParams{" 9669 + Integer.toHexString(System.identityHashCode(this)) 9670 + " " + mStats.packageName + "}"; 9671 } 9672 9673 @Override 9674 void handleStartCopy() throws RemoteException { 9675 synchronized (mInstallLock) { 9676 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 9677 } 9678 9679 if (mSuccess) { 9680 final boolean mounted; 9681 if (Environment.isExternalStorageEmulated()) { 9682 mounted = true; 9683 } else { 9684 final String status = Environment.getExternalStorageState(); 9685 mounted = (Environment.MEDIA_MOUNTED.equals(status) 9686 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 9687 } 9688 9689 if (mounted) { 9690 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 9691 9692 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 9693 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 9694 9695 mStats.externalDataSize = calculateDirectorySize(mContainerService, 9696 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 9697 9698 // Always subtract cache size, since it's a subdirectory 9699 mStats.externalDataSize -= mStats.externalCacheSize; 9700 9701 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 9702 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 9703 9704 mStats.externalObbSize = calculateDirectorySize(mContainerService, 9705 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 9706 } 9707 } 9708 } 9709 9710 @Override 9711 void handleReturnCode() { 9712 if (mObserver != null) { 9713 try { 9714 mObserver.onGetStatsCompleted(mStats, mSuccess); 9715 } catch (RemoteException e) { 9716 Slog.i(TAG, "Observer no longer exists."); 9717 } 9718 } 9719 } 9720 9721 @Override 9722 void handleServiceError() { 9723 Slog.e(TAG, "Could not measure application " + mStats.packageName 9724 + " external storage"); 9725 } 9726 } 9727 9728 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 9729 throws RemoteException { 9730 long result = 0; 9731 for (File path : paths) { 9732 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 9733 } 9734 return result; 9735 } 9736 9737 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 9738 for (File path : paths) { 9739 try { 9740 mcs.clearDirectory(path.getAbsolutePath()); 9741 } catch (RemoteException e) { 9742 } 9743 } 9744 } 9745 9746 static class OriginInfo { 9747 /** 9748 * Location where install is coming from, before it has been 9749 * copied/renamed into place. This could be a single monolithic APK 9750 * file, or a cluster directory. This location may be untrusted. 9751 */ 9752 final File file; 9753 final String cid; 9754 9755 /** 9756 * Flag indicating that {@link #file} or {@link #cid} has already been 9757 * staged, meaning downstream users don't need to defensively copy the 9758 * contents. 9759 */ 9760 final boolean staged; 9761 9762 /** 9763 * Flag indicating that {@link #file} or {@link #cid} is an already 9764 * installed app that is being moved. 9765 */ 9766 final boolean existing; 9767 9768 final String resolvedPath; 9769 final File resolvedFile; 9770 9771 static OriginInfo fromNothing() { 9772 return new OriginInfo(null, null, false, false); 9773 } 9774 9775 static OriginInfo fromUntrustedFile(File file) { 9776 return new OriginInfo(file, null, false, false); 9777 } 9778 9779 static OriginInfo fromExistingFile(File file) { 9780 return new OriginInfo(file, null, false, true); 9781 } 9782 9783 static OriginInfo fromStagedFile(File file) { 9784 return new OriginInfo(file, null, true, false); 9785 } 9786 9787 static OriginInfo fromStagedContainer(String cid) { 9788 return new OriginInfo(null, cid, true, false); 9789 } 9790 9791 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 9792 this.file = file; 9793 this.cid = cid; 9794 this.staged = staged; 9795 this.existing = existing; 9796 9797 if (cid != null) { 9798 resolvedPath = PackageHelper.getSdDir(cid); 9799 resolvedFile = new File(resolvedPath); 9800 } else if (file != null) { 9801 resolvedPath = file.getAbsolutePath(); 9802 resolvedFile = file; 9803 } else { 9804 resolvedPath = null; 9805 resolvedFile = null; 9806 } 9807 } 9808 } 9809 9810 class MoveInfo { 9811 final int moveId; 9812 final String fromUuid; 9813 final String toUuid; 9814 final String packageName; 9815 final String dataAppName; 9816 final int appId; 9817 final String seinfo; 9818 9819 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 9820 String dataAppName, int appId, String seinfo) { 9821 this.moveId = moveId; 9822 this.fromUuid = fromUuid; 9823 this.toUuid = toUuid; 9824 this.packageName = packageName; 9825 this.dataAppName = dataAppName; 9826 this.appId = appId; 9827 this.seinfo = seinfo; 9828 } 9829 } 9830 9831 class InstallParams extends HandlerParams { 9832 final OriginInfo origin; 9833 final MoveInfo move; 9834 final IPackageInstallObserver2 observer; 9835 int installFlags; 9836 final String installerPackageName; 9837 final String volumeUuid; 9838 final VerificationParams verificationParams; 9839 private InstallArgs mArgs; 9840 private int mRet; 9841 final String packageAbiOverride; 9842 9843 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 9844 int installFlags, String installerPackageName, String volumeUuid, 9845 VerificationParams verificationParams, UserHandle user, String packageAbiOverride) { 9846 super(user); 9847 this.origin = origin; 9848 this.move = move; 9849 this.observer = observer; 9850 this.installFlags = installFlags; 9851 this.installerPackageName = installerPackageName; 9852 this.volumeUuid = volumeUuid; 9853 this.verificationParams = verificationParams; 9854 this.packageAbiOverride = packageAbiOverride; 9855 } 9856 9857 @Override 9858 public String toString() { 9859 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 9860 + " file=" + origin.file + " cid=" + origin.cid + "}"; 9861 } 9862 9863 public ManifestDigest getManifestDigest() { 9864 if (verificationParams == null) { 9865 return null; 9866 } 9867 return verificationParams.getManifestDigest(); 9868 } 9869 9870 private int installLocationPolicy(PackageInfoLite pkgLite) { 9871 String packageName = pkgLite.packageName; 9872 int installLocation = pkgLite.installLocation; 9873 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9874 // reader 9875 synchronized (mPackages) { 9876 PackageParser.Package pkg = mPackages.get(packageName); 9877 if (pkg != null) { 9878 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 9879 // Check for downgrading. 9880 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 9881 try { 9882 checkDowngrade(pkg, pkgLite); 9883 } catch (PackageManagerException e) { 9884 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 9885 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 9886 } 9887 } 9888 // Check for updated system application. 9889 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9890 if (onSd) { 9891 Slog.w(TAG, "Cannot install update to system app on sdcard"); 9892 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 9893 } 9894 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9895 } else { 9896 if (onSd) { 9897 // Install flag overrides everything. 9898 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9899 } 9900 // If current upgrade specifies particular preference 9901 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 9902 // Application explicitly specified internal. 9903 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9904 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 9905 // App explictly prefers external. Let policy decide 9906 } else { 9907 // Prefer previous location 9908 if (isExternal(pkg)) { 9909 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9910 } 9911 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 9912 } 9913 } 9914 } else { 9915 // Invalid install. Return error code 9916 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 9917 } 9918 } 9919 } 9920 // All the special cases have been taken care of. 9921 // Return result based on recommended install location. 9922 if (onSd) { 9923 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 9924 } 9925 return pkgLite.recommendedInstallLocation; 9926 } 9927 9928 /* 9929 * Invoke remote method to get package information and install 9930 * location values. Override install location based on default 9931 * policy if needed and then create install arguments based 9932 * on the install location. 9933 */ 9934 public void handleStartCopy() throws RemoteException { 9935 int ret = PackageManager.INSTALL_SUCCEEDED; 9936 9937 // If we're already staged, we've firmly committed to an install location 9938 if (origin.staged) { 9939 if (origin.file != null) { 9940 installFlags |= PackageManager.INSTALL_INTERNAL; 9941 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9942 } else if (origin.cid != null) { 9943 installFlags |= PackageManager.INSTALL_EXTERNAL; 9944 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9945 } else { 9946 throw new IllegalStateException("Invalid stage location"); 9947 } 9948 } 9949 9950 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9951 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 9952 9953 PackageInfoLite pkgLite = null; 9954 9955 if (onInt && onSd) { 9956 // Check if both bits are set. 9957 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 9958 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9959 } else { 9960 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 9961 packageAbiOverride); 9962 9963 /* 9964 * If we have too little free space, try to free cache 9965 * before giving up. 9966 */ 9967 if (!origin.staged && pkgLite.recommendedInstallLocation 9968 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9969 // TODO: focus freeing disk space on the target device 9970 final StorageManager storage = StorageManager.from(mContext); 9971 final long lowThreshold = storage.getStorageLowBytes( 9972 Environment.getDataDirectory()); 9973 9974 final long sizeBytes = mContainerService.calculateInstalledSize( 9975 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 9976 9977 if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) { 9978 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 9979 installFlags, packageAbiOverride); 9980 } 9981 9982 /* 9983 * The cache free must have deleted the file we 9984 * downloaded to install. 9985 * 9986 * TODO: fix the "freeCache" call to not delete 9987 * the file we care about. 9988 */ 9989 if (pkgLite.recommendedInstallLocation 9990 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9991 pkgLite.recommendedInstallLocation 9992 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 9993 } 9994 } 9995 } 9996 9997 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9998 int loc = pkgLite.recommendedInstallLocation; 9999 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 10000 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 10001 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 10002 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 10003 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 10004 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10005 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 10006 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 10007 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 10008 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 10009 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 10010 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 10011 } else { 10012 // Override with defaults if needed. 10013 loc = installLocationPolicy(pkgLite); 10014 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 10015 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 10016 } else if (!onSd && !onInt) { 10017 // Override install location with flags 10018 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 10019 // Set the flag to install on external media. 10020 installFlags |= PackageManager.INSTALL_EXTERNAL; 10021 installFlags &= ~PackageManager.INSTALL_INTERNAL; 10022 } else { 10023 // Make sure the flag for installing on external 10024 // media is unset 10025 installFlags |= PackageManager.INSTALL_INTERNAL; 10026 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 10027 } 10028 } 10029 } 10030 } 10031 10032 final InstallArgs args = createInstallArgs(this); 10033 mArgs = args; 10034 10035 if (ret == PackageManager.INSTALL_SUCCEEDED) { 10036 /* 10037 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 10038 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 10039 */ 10040 int userIdentifier = getUser().getIdentifier(); 10041 if (userIdentifier == UserHandle.USER_ALL 10042 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) { 10043 userIdentifier = UserHandle.USER_OWNER; 10044 } 10045 10046 /* 10047 * Determine if we have any installed package verifiers. If we 10048 * do, then we'll defer to them to verify the packages. 10049 */ 10050 final int requiredUid = mRequiredVerifierPackage == null ? -1 10051 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 10052 if (!origin.existing && requiredUid != -1 10053 && isVerificationEnabled(userIdentifier, installFlags)) { 10054 final Intent verification = new Intent( 10055 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 10056 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10057 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 10058 PACKAGE_MIME_TYPE); 10059 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10060 10061 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 10062 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 10063 0 /* TODO: Which userId? */); 10064 10065 if (DEBUG_VERIFY) { 10066 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 10067 + verification.toString() + " with " + pkgLite.verifiers.length 10068 + " optional verifiers"); 10069 } 10070 10071 final int verificationId = mPendingVerificationToken++; 10072 10073 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10074 10075 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 10076 installerPackageName); 10077 10078 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 10079 installFlags); 10080 10081 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 10082 pkgLite.packageName); 10083 10084 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 10085 pkgLite.versionCode); 10086 10087 if (verificationParams != null) { 10088 if (verificationParams.getVerificationURI() != null) { 10089 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 10090 verificationParams.getVerificationURI()); 10091 } 10092 if (verificationParams.getOriginatingURI() != null) { 10093 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 10094 verificationParams.getOriginatingURI()); 10095 } 10096 if (verificationParams.getReferrer() != null) { 10097 verification.putExtra(Intent.EXTRA_REFERRER, 10098 verificationParams.getReferrer()); 10099 } 10100 if (verificationParams.getOriginatingUid() >= 0) { 10101 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 10102 verificationParams.getOriginatingUid()); 10103 } 10104 if (verificationParams.getInstallerUid() >= 0) { 10105 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 10106 verificationParams.getInstallerUid()); 10107 } 10108 } 10109 10110 final PackageVerificationState verificationState = new PackageVerificationState( 10111 requiredUid, args); 10112 10113 mPendingVerification.append(verificationId, verificationState); 10114 10115 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 10116 receivers, verificationState); 10117 10118 /* 10119 * If any sufficient verifiers were listed in the package 10120 * manifest, attempt to ask them. 10121 */ 10122 if (sufficientVerifiers != null) { 10123 final int N = sufficientVerifiers.size(); 10124 if (N == 0) { 10125 Slog.i(TAG, "Additional verifiers required, but none installed."); 10126 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 10127 } else { 10128 for (int i = 0; i < N; i++) { 10129 final ComponentName verifierComponent = sufficientVerifiers.get(i); 10130 10131 final Intent sufficientIntent = new Intent(verification); 10132 sufficientIntent.setComponent(verifierComponent); 10133 10134 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 10135 } 10136 } 10137 } 10138 10139 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 10140 mRequiredVerifierPackage, receivers); 10141 if (ret == PackageManager.INSTALL_SUCCEEDED 10142 && mRequiredVerifierPackage != null) { 10143 /* 10144 * Send the intent to the required verification agent, 10145 * but only start the verification timeout after the 10146 * target BroadcastReceivers have run. 10147 */ 10148 verification.setComponent(requiredVerifierComponent); 10149 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 10150 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10151 new BroadcastReceiver() { 10152 @Override 10153 public void onReceive(Context context, Intent intent) { 10154 final Message msg = mHandler 10155 .obtainMessage(CHECK_PENDING_VERIFICATION); 10156 msg.arg1 = verificationId; 10157 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 10158 } 10159 }, null, 0, null, null); 10160 10161 /* 10162 * We don't want the copy to proceed until verification 10163 * succeeds, so null out this field. 10164 */ 10165 mArgs = null; 10166 } 10167 } else { 10168 /* 10169 * No package verification is enabled, so immediately start 10170 * the remote call to initiate copy using temporary file. 10171 */ 10172 ret = args.copyApk(mContainerService, true); 10173 } 10174 } 10175 10176 mRet = ret; 10177 } 10178 10179 @Override 10180 void handleReturnCode() { 10181 // If mArgs is null, then MCS couldn't be reached. When it 10182 // reconnects, it will try again to install. At that point, this 10183 // will succeed. 10184 if (mArgs != null) { 10185 processPendingInstall(mArgs, mRet); 10186 } 10187 } 10188 10189 @Override 10190 void handleServiceError() { 10191 mArgs = createInstallArgs(this); 10192 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10193 } 10194 10195 public boolean isForwardLocked() { 10196 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 10197 } 10198 } 10199 10200 /** 10201 * Used during creation of InstallArgs 10202 * 10203 * @param installFlags package installation flags 10204 * @return true if should be installed on external storage 10205 */ 10206 private static boolean installOnExternalAsec(int installFlags) { 10207 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 10208 return false; 10209 } 10210 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 10211 return true; 10212 } 10213 return false; 10214 } 10215 10216 /** 10217 * Used during creation of InstallArgs 10218 * 10219 * @param installFlags package installation flags 10220 * @return true if should be installed as forward locked 10221 */ 10222 private static boolean installForwardLocked(int installFlags) { 10223 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 10224 } 10225 10226 private InstallArgs createInstallArgs(InstallParams params) { 10227 if (params.move != null) { 10228 return new MoveInstallArgs(params); 10229 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 10230 return new AsecInstallArgs(params); 10231 } else { 10232 return new FileInstallArgs(params); 10233 } 10234 } 10235 10236 /** 10237 * Create args that describe an existing installed package. Typically used 10238 * when cleaning up old installs, or used as a move source. 10239 */ 10240 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 10241 String resourcePath, String[] instructionSets) { 10242 final boolean isInAsec; 10243 if (installOnExternalAsec(installFlags)) { 10244 /* Apps on SD card are always in ASEC containers. */ 10245 isInAsec = true; 10246 } else if (installForwardLocked(installFlags) 10247 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 10248 /* 10249 * Forward-locked apps are only in ASEC containers if they're the 10250 * new style 10251 */ 10252 isInAsec = true; 10253 } else { 10254 isInAsec = false; 10255 } 10256 10257 if (isInAsec) { 10258 return new AsecInstallArgs(codePath, instructionSets, 10259 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 10260 } else { 10261 return new FileInstallArgs(codePath, resourcePath, instructionSets); 10262 } 10263 } 10264 10265 static abstract class InstallArgs { 10266 /** @see InstallParams#origin */ 10267 final OriginInfo origin; 10268 /** @see InstallParams#move */ 10269 final MoveInfo move; 10270 10271 final IPackageInstallObserver2 observer; 10272 // Always refers to PackageManager flags only 10273 final int installFlags; 10274 final String installerPackageName; 10275 final String volumeUuid; 10276 final ManifestDigest manifestDigest; 10277 final UserHandle user; 10278 final String abiOverride; 10279 10280 // The list of instruction sets supported by this app. This is currently 10281 // only used during the rmdex() phase to clean up resources. We can get rid of this 10282 // if we move dex files under the common app path. 10283 /* nullable */ String[] instructionSets; 10284 10285 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 10286 int installFlags, String installerPackageName, String volumeUuid, 10287 ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, 10288 String abiOverride) { 10289 this.origin = origin; 10290 this.move = move; 10291 this.installFlags = installFlags; 10292 this.observer = observer; 10293 this.installerPackageName = installerPackageName; 10294 this.volumeUuid = volumeUuid; 10295 this.manifestDigest = manifestDigest; 10296 this.user = user; 10297 this.instructionSets = instructionSets; 10298 this.abiOverride = abiOverride; 10299 } 10300 10301 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 10302 abstract int doPreInstall(int status); 10303 10304 /** 10305 * Rename package into final resting place. All paths on the given 10306 * scanned package should be updated to reflect the rename. 10307 */ 10308 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 10309 abstract int doPostInstall(int status, int uid); 10310 10311 /** @see PackageSettingBase#codePathString */ 10312 abstract String getCodePath(); 10313 /** @see PackageSettingBase#resourcePathString */ 10314 abstract String getResourcePath(); 10315 10316 // Need installer lock especially for dex file removal. 10317 abstract void cleanUpResourcesLI(); 10318 abstract boolean doPostDeleteLI(boolean delete); 10319 10320 /** 10321 * Called before the source arguments are copied. This is used mostly 10322 * for MoveParams when it needs to read the source file to put it in the 10323 * destination. 10324 */ 10325 int doPreCopy() { 10326 return PackageManager.INSTALL_SUCCEEDED; 10327 } 10328 10329 /** 10330 * Called after the source arguments are copied. This is used mostly for 10331 * MoveParams when it needs to read the source file to put it in the 10332 * destination. 10333 * 10334 * @return 10335 */ 10336 int doPostCopy(int uid) { 10337 return PackageManager.INSTALL_SUCCEEDED; 10338 } 10339 10340 protected boolean isFwdLocked() { 10341 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 10342 } 10343 10344 protected boolean isExternalAsec() { 10345 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 10346 } 10347 10348 UserHandle getUser() { 10349 return user; 10350 } 10351 } 10352 10353 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 10354 if (!allCodePaths.isEmpty()) { 10355 if (instructionSets == null) { 10356 throw new IllegalStateException("instructionSet == null"); 10357 } 10358 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 10359 for (String codePath : allCodePaths) { 10360 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 10361 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 10362 if (retCode < 0) { 10363 Slog.w(TAG, "Couldn't remove dex file for package: " 10364 + " at location " + codePath + ", retcode=" + retCode); 10365 // we don't consider this to be a failure of the core package deletion 10366 } 10367 } 10368 } 10369 } 10370 } 10371 10372 /** 10373 * Logic to handle installation of non-ASEC applications, including copying 10374 * and renaming logic. 10375 */ 10376 class FileInstallArgs extends InstallArgs { 10377 private File codeFile; 10378 private File resourceFile; 10379 10380 // Example topology: 10381 // /data/app/com.example/base.apk 10382 // /data/app/com.example/split_foo.apk 10383 // /data/app/com.example/lib/arm/libfoo.so 10384 // /data/app/com.example/lib/arm64/libfoo.so 10385 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 10386 10387 /** New install */ 10388 FileInstallArgs(InstallParams params) { 10389 super(params.origin, params.move, params.observer, params.installFlags, 10390 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10391 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10392 if (isFwdLocked()) { 10393 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 10394 } 10395 } 10396 10397 /** Existing install */ 10398 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 10399 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets, 10400 null); 10401 this.codeFile = (codePath != null) ? new File(codePath) : null; 10402 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 10403 } 10404 10405 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10406 if (origin.staged) { 10407 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 10408 codeFile = origin.file; 10409 resourceFile = origin.file; 10410 return PackageManager.INSTALL_SUCCEEDED; 10411 } 10412 10413 try { 10414 final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid); 10415 codeFile = tempDir; 10416 resourceFile = tempDir; 10417 } catch (IOException e) { 10418 Slog.w(TAG, "Failed to create copy file: " + e); 10419 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 10420 } 10421 10422 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 10423 @Override 10424 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 10425 if (!FileUtils.isValidExtFilename(name)) { 10426 throw new IllegalArgumentException("Invalid filename: " + name); 10427 } 10428 try { 10429 final File file = new File(codeFile, name); 10430 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 10431 O_RDWR | O_CREAT, 0644); 10432 Os.chmod(file.getAbsolutePath(), 0644); 10433 return new ParcelFileDescriptor(fd); 10434 } catch (ErrnoException e) { 10435 throw new RemoteException("Failed to open: " + e.getMessage()); 10436 } 10437 } 10438 }; 10439 10440 int ret = PackageManager.INSTALL_SUCCEEDED; 10441 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 10442 if (ret != PackageManager.INSTALL_SUCCEEDED) { 10443 Slog.e(TAG, "Failed to copy package"); 10444 return ret; 10445 } 10446 10447 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 10448 NativeLibraryHelper.Handle handle = null; 10449 try { 10450 handle = NativeLibraryHelper.Handle.create(codeFile); 10451 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 10452 abiOverride); 10453 } catch (IOException e) { 10454 Slog.e(TAG, "Copying native libraries failed", e); 10455 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10456 } finally { 10457 IoUtils.closeQuietly(handle); 10458 } 10459 10460 return ret; 10461 } 10462 10463 int doPreInstall(int status) { 10464 if (status != PackageManager.INSTALL_SUCCEEDED) { 10465 cleanUp(); 10466 } 10467 return status; 10468 } 10469 10470 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10471 if (status != PackageManager.INSTALL_SUCCEEDED) { 10472 cleanUp(); 10473 return false; 10474 } 10475 10476 final File targetDir = codeFile.getParentFile(); 10477 final File beforeCodeFile = codeFile; 10478 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 10479 10480 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 10481 try { 10482 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 10483 } catch (ErrnoException e) { 10484 Slog.w(TAG, "Failed to rename", e); 10485 return false; 10486 } 10487 10488 if (!SELinux.restoreconRecursive(afterCodeFile)) { 10489 Slog.w(TAG, "Failed to restorecon"); 10490 return false; 10491 } 10492 10493 // Reflect the rename internally 10494 codeFile = afterCodeFile; 10495 resourceFile = afterCodeFile; 10496 10497 // Reflect the rename in scanned details 10498 pkg.codePath = afterCodeFile.getAbsolutePath(); 10499 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10500 pkg.baseCodePath); 10501 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10502 pkg.splitCodePaths); 10503 10504 // Reflect the rename in app info 10505 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10506 pkg.applicationInfo.setCodePath(pkg.codePath); 10507 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10508 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10509 pkg.applicationInfo.setResourcePath(pkg.codePath); 10510 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10511 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10512 10513 return true; 10514 } 10515 10516 int doPostInstall(int status, int uid) { 10517 if (status != PackageManager.INSTALL_SUCCEEDED) { 10518 cleanUp(); 10519 } 10520 return status; 10521 } 10522 10523 @Override 10524 String getCodePath() { 10525 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 10526 } 10527 10528 @Override 10529 String getResourcePath() { 10530 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 10531 } 10532 10533 private boolean cleanUp() { 10534 if (codeFile == null || !codeFile.exists()) { 10535 return false; 10536 } 10537 10538 if (codeFile.isDirectory()) { 10539 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 10540 } else { 10541 codeFile.delete(); 10542 } 10543 10544 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 10545 resourceFile.delete(); 10546 } 10547 10548 return true; 10549 } 10550 10551 void cleanUpResourcesLI() { 10552 // Try enumerating all code paths before deleting 10553 List<String> allCodePaths = Collections.EMPTY_LIST; 10554 if (codeFile != null && codeFile.exists()) { 10555 try { 10556 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10557 allCodePaths = pkg.getAllCodePaths(); 10558 } catch (PackageParserException e) { 10559 // Ignored; we tried our best 10560 } 10561 } 10562 10563 cleanUp(); 10564 removeDexFiles(allCodePaths, instructionSets); 10565 } 10566 10567 boolean doPostDeleteLI(boolean delete) { 10568 // XXX err, shouldn't we respect the delete flag? 10569 cleanUpResourcesLI(); 10570 return true; 10571 } 10572 } 10573 10574 private boolean isAsecExternal(String cid) { 10575 final String asecPath = PackageHelper.getSdFilesystem(cid); 10576 return !asecPath.startsWith(mAsecInternalPath); 10577 } 10578 10579 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 10580 PackageManagerException { 10581 if (copyRet < 0) { 10582 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 10583 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 10584 throw new PackageManagerException(copyRet, message); 10585 } 10586 } 10587 } 10588 10589 /** 10590 * Extract the MountService "container ID" from the full code path of an 10591 * .apk. 10592 */ 10593 static String cidFromCodePath(String fullCodePath) { 10594 int eidx = fullCodePath.lastIndexOf("/"); 10595 String subStr1 = fullCodePath.substring(0, eidx); 10596 int sidx = subStr1.lastIndexOf("/"); 10597 return subStr1.substring(sidx+1, eidx); 10598 } 10599 10600 /** 10601 * Logic to handle installation of ASEC applications, including copying and 10602 * renaming logic. 10603 */ 10604 class AsecInstallArgs extends InstallArgs { 10605 static final String RES_FILE_NAME = "pkg.apk"; 10606 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 10607 10608 String cid; 10609 String packagePath; 10610 String resourcePath; 10611 10612 /** New install */ 10613 AsecInstallArgs(InstallParams params) { 10614 super(params.origin, params.move, params.observer, params.installFlags, 10615 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10616 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10617 } 10618 10619 /** Existing install */ 10620 AsecInstallArgs(String fullCodePath, String[] instructionSets, 10621 boolean isExternal, boolean isForwardLocked) { 10622 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 10623 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10624 instructionSets, null); 10625 // Hackily pretend we're still looking at a full code path 10626 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 10627 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 10628 } 10629 10630 // Extract cid from fullCodePath 10631 int eidx = fullCodePath.lastIndexOf("/"); 10632 String subStr1 = fullCodePath.substring(0, eidx); 10633 int sidx = subStr1.lastIndexOf("/"); 10634 cid = subStr1.substring(sidx+1, eidx); 10635 setMountPath(subStr1); 10636 } 10637 10638 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 10639 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 10640 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, 10641 instructionSets, null); 10642 this.cid = cid; 10643 setMountPath(PackageHelper.getSdDir(cid)); 10644 } 10645 10646 void createCopyFile() { 10647 cid = mInstallerService.allocateExternalStageCidLegacy(); 10648 } 10649 10650 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 10651 if (origin.staged) { 10652 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 10653 cid = origin.cid; 10654 setMountPath(PackageHelper.getSdDir(cid)); 10655 return PackageManager.INSTALL_SUCCEEDED; 10656 } 10657 10658 if (temp) { 10659 createCopyFile(); 10660 } else { 10661 /* 10662 * Pre-emptively destroy the container since it's destroyed if 10663 * copying fails due to it existing anyway. 10664 */ 10665 PackageHelper.destroySdDir(cid); 10666 } 10667 10668 final String newMountPath = imcs.copyPackageToContainer( 10669 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 10670 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 10671 10672 if (newMountPath != null) { 10673 setMountPath(newMountPath); 10674 return PackageManager.INSTALL_SUCCEEDED; 10675 } else { 10676 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10677 } 10678 } 10679 10680 @Override 10681 String getCodePath() { 10682 return packagePath; 10683 } 10684 10685 @Override 10686 String getResourcePath() { 10687 return resourcePath; 10688 } 10689 10690 int doPreInstall(int status) { 10691 if (status != PackageManager.INSTALL_SUCCEEDED) { 10692 // Destroy container 10693 PackageHelper.destroySdDir(cid); 10694 } else { 10695 boolean mounted = PackageHelper.isContainerMounted(cid); 10696 if (!mounted) { 10697 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 10698 Process.SYSTEM_UID); 10699 if (newMountPath != null) { 10700 setMountPath(newMountPath); 10701 } else { 10702 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10703 } 10704 } 10705 } 10706 return status; 10707 } 10708 10709 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10710 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 10711 String newMountPath = null; 10712 if (PackageHelper.isContainerMounted(cid)) { 10713 // Unmount the container 10714 if (!PackageHelper.unMountSdDir(cid)) { 10715 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 10716 return false; 10717 } 10718 } 10719 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10720 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 10721 " which might be stale. Will try to clean up."); 10722 // Clean up the stale container and proceed to recreate. 10723 if (!PackageHelper.destroySdDir(newCacheId)) { 10724 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 10725 return false; 10726 } 10727 // Successfully cleaned up stale container. Try to rename again. 10728 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 10729 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 10730 + " inspite of cleaning it up."); 10731 return false; 10732 } 10733 } 10734 if (!PackageHelper.isContainerMounted(newCacheId)) { 10735 Slog.w(TAG, "Mounting container " + newCacheId); 10736 newMountPath = PackageHelper.mountSdDir(newCacheId, 10737 getEncryptKey(), Process.SYSTEM_UID); 10738 } else { 10739 newMountPath = PackageHelper.getSdDir(newCacheId); 10740 } 10741 if (newMountPath == null) { 10742 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 10743 return false; 10744 } 10745 Log.i(TAG, "Succesfully renamed " + cid + 10746 " to " + newCacheId + 10747 " at new path: " + newMountPath); 10748 cid = newCacheId; 10749 10750 final File beforeCodeFile = new File(packagePath); 10751 setMountPath(newMountPath); 10752 final File afterCodeFile = new File(packagePath); 10753 10754 // Reflect the rename in scanned details 10755 pkg.codePath = afterCodeFile.getAbsolutePath(); 10756 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10757 pkg.baseCodePath); 10758 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 10759 pkg.splitCodePaths); 10760 10761 // Reflect the rename in app info 10762 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10763 pkg.applicationInfo.setCodePath(pkg.codePath); 10764 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10765 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10766 pkg.applicationInfo.setResourcePath(pkg.codePath); 10767 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10768 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10769 10770 return true; 10771 } 10772 10773 private void setMountPath(String mountPath) { 10774 final File mountFile = new File(mountPath); 10775 10776 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 10777 if (monolithicFile.exists()) { 10778 packagePath = monolithicFile.getAbsolutePath(); 10779 if (isFwdLocked()) { 10780 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 10781 } else { 10782 resourcePath = packagePath; 10783 } 10784 } else { 10785 packagePath = mountFile.getAbsolutePath(); 10786 resourcePath = packagePath; 10787 } 10788 } 10789 10790 int doPostInstall(int status, int uid) { 10791 if (status != PackageManager.INSTALL_SUCCEEDED) { 10792 cleanUp(); 10793 } else { 10794 final int groupOwner; 10795 final String protectedFile; 10796 if (isFwdLocked()) { 10797 groupOwner = UserHandle.getSharedAppGid(uid); 10798 protectedFile = RES_FILE_NAME; 10799 } else { 10800 groupOwner = -1; 10801 protectedFile = null; 10802 } 10803 10804 if (uid < Process.FIRST_APPLICATION_UID 10805 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 10806 Slog.e(TAG, "Failed to finalize " + cid); 10807 PackageHelper.destroySdDir(cid); 10808 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10809 } 10810 10811 boolean mounted = PackageHelper.isContainerMounted(cid); 10812 if (!mounted) { 10813 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 10814 } 10815 } 10816 return status; 10817 } 10818 10819 private void cleanUp() { 10820 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 10821 10822 // Destroy secure container 10823 PackageHelper.destroySdDir(cid); 10824 } 10825 10826 private List<String> getAllCodePaths() { 10827 final File codeFile = new File(getCodePath()); 10828 if (codeFile != null && codeFile.exists()) { 10829 try { 10830 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 10831 return pkg.getAllCodePaths(); 10832 } catch (PackageParserException e) { 10833 // Ignored; we tried our best 10834 } 10835 } 10836 return Collections.EMPTY_LIST; 10837 } 10838 10839 void cleanUpResourcesLI() { 10840 // Enumerate all code paths before deleting 10841 cleanUpResourcesLI(getAllCodePaths()); 10842 } 10843 10844 private void cleanUpResourcesLI(List<String> allCodePaths) { 10845 cleanUp(); 10846 removeDexFiles(allCodePaths, instructionSets); 10847 } 10848 10849 String getPackageName() { 10850 return getAsecPackageName(cid); 10851 } 10852 10853 boolean doPostDeleteLI(boolean delete) { 10854 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 10855 final List<String> allCodePaths = getAllCodePaths(); 10856 boolean mounted = PackageHelper.isContainerMounted(cid); 10857 if (mounted) { 10858 // Unmount first 10859 if (PackageHelper.unMountSdDir(cid)) { 10860 mounted = false; 10861 } 10862 } 10863 if (!mounted && delete) { 10864 cleanUpResourcesLI(allCodePaths); 10865 } 10866 return !mounted; 10867 } 10868 10869 @Override 10870 int doPreCopy() { 10871 if (isFwdLocked()) { 10872 if (!PackageHelper.fixSdPermissions(cid, 10873 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 10874 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10875 } 10876 } 10877 10878 return PackageManager.INSTALL_SUCCEEDED; 10879 } 10880 10881 @Override 10882 int doPostCopy(int uid) { 10883 if (isFwdLocked()) { 10884 if (uid < Process.FIRST_APPLICATION_UID 10885 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 10886 RES_FILE_NAME)) { 10887 Slog.e(TAG, "Failed to finalize " + cid); 10888 PackageHelper.destroySdDir(cid); 10889 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 10890 } 10891 } 10892 10893 return PackageManager.INSTALL_SUCCEEDED; 10894 } 10895 } 10896 10897 /** 10898 * Logic to handle movement of existing installed applications. 10899 */ 10900 class MoveInstallArgs extends InstallArgs { 10901 private File codeFile; 10902 private File resourceFile; 10903 10904 /** New install */ 10905 MoveInstallArgs(InstallParams params) { 10906 super(params.origin, params.move, params.observer, params.installFlags, 10907 params.installerPackageName, params.volumeUuid, params.getManifestDigest(), 10908 params.getUser(), null /* instruction sets */, params.packageAbiOverride); 10909 } 10910 10911 int copyApk(IMediaContainerService imcs, boolean temp) { 10912 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 10913 + move.fromUuid + " to " + move.toUuid); 10914 synchronized (mInstaller) { 10915 if (mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 10916 move.dataAppName, move.appId, move.seinfo) != 0) { 10917 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 10918 } 10919 } 10920 10921 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 10922 resourceFile = codeFile; 10923 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 10924 10925 return PackageManager.INSTALL_SUCCEEDED; 10926 } 10927 10928 int doPreInstall(int status) { 10929 if (status != PackageManager.INSTALL_SUCCEEDED) { 10930 cleanUp(); 10931 } 10932 return status; 10933 } 10934 10935 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 10936 if (status != PackageManager.INSTALL_SUCCEEDED) { 10937 cleanUp(); 10938 return false; 10939 } 10940 10941 // Reflect the move in app info 10942 pkg.applicationInfo.volumeUuid = pkg.volumeUuid; 10943 pkg.applicationInfo.setCodePath(pkg.codePath); 10944 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 10945 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 10946 pkg.applicationInfo.setResourcePath(pkg.codePath); 10947 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 10948 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 10949 10950 return true; 10951 } 10952 10953 int doPostInstall(int status, int uid) { 10954 if (status != PackageManager.INSTALL_SUCCEEDED) { 10955 cleanUp(); 10956 } 10957 return status; 10958 } 10959 10960 @Override 10961 String getCodePath() { 10962 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 10963 } 10964 10965 @Override 10966 String getResourcePath() { 10967 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 10968 } 10969 10970 private boolean cleanUp() { 10971 if (codeFile == null || !codeFile.exists()) { 10972 return false; 10973 } 10974 10975 if (codeFile.isDirectory()) { 10976 mInstaller.rmPackageDir(codeFile.getAbsolutePath()); 10977 } else { 10978 codeFile.delete(); 10979 } 10980 10981 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 10982 resourceFile.delete(); 10983 } 10984 10985 return true; 10986 } 10987 10988 void cleanUpResourcesLI() { 10989 cleanUp(); 10990 } 10991 10992 boolean doPostDeleteLI(boolean delete) { 10993 // XXX err, shouldn't we respect the delete flag? 10994 cleanUpResourcesLI(); 10995 return true; 10996 } 10997 } 10998 10999 static String getAsecPackageName(String packageCid) { 11000 int idx = packageCid.lastIndexOf("-"); 11001 if (idx == -1) { 11002 return packageCid; 11003 } 11004 return packageCid.substring(0, idx); 11005 } 11006 11007 // Utility method used to create code paths based on package name and available index. 11008 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 11009 String idxStr = ""; 11010 int idx = 1; 11011 // Fall back to default value of idx=1 if prefix is not 11012 // part of oldCodePath 11013 if (oldCodePath != null) { 11014 String subStr = oldCodePath; 11015 // Drop the suffix right away 11016 if (suffix != null && subStr.endsWith(suffix)) { 11017 subStr = subStr.substring(0, subStr.length() - suffix.length()); 11018 } 11019 // If oldCodePath already contains prefix find out the 11020 // ending index to either increment or decrement. 11021 int sidx = subStr.lastIndexOf(prefix); 11022 if (sidx != -1) { 11023 subStr = subStr.substring(sidx + prefix.length()); 11024 if (subStr != null) { 11025 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 11026 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 11027 } 11028 try { 11029 idx = Integer.parseInt(subStr); 11030 if (idx <= 1) { 11031 idx++; 11032 } else { 11033 idx--; 11034 } 11035 } catch(NumberFormatException e) { 11036 } 11037 } 11038 } 11039 } 11040 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 11041 return prefix + idxStr; 11042 } 11043 11044 private File getNextCodePath(File targetDir, String packageName) { 11045 int suffix = 1; 11046 File result; 11047 do { 11048 result = new File(targetDir, packageName + "-" + suffix); 11049 suffix++; 11050 } while (result.exists()); 11051 return result; 11052 } 11053 11054 // Utility method that returns the relative package path with respect 11055 // to the installation directory. Like say for /data/data/com.test-1.apk 11056 // string com.test-1 is returned. 11057 static String deriveCodePathName(String codePath) { 11058 if (codePath == null) { 11059 return null; 11060 } 11061 final File codeFile = new File(codePath); 11062 final String name = codeFile.getName(); 11063 if (codeFile.isDirectory()) { 11064 return name; 11065 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 11066 final int lastDot = name.lastIndexOf('.'); 11067 return name.substring(0, lastDot); 11068 } else { 11069 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 11070 return null; 11071 } 11072 } 11073 11074 class PackageInstalledInfo { 11075 String name; 11076 int uid; 11077 // The set of users that originally had this package installed. 11078 int[] origUsers; 11079 // The set of users that now have this package installed. 11080 int[] newUsers; 11081 PackageParser.Package pkg; 11082 int returnCode; 11083 String returnMsg; 11084 PackageRemovedInfo removedInfo; 11085 11086 public void setError(int code, String msg) { 11087 returnCode = code; 11088 returnMsg = msg; 11089 Slog.w(TAG, msg); 11090 } 11091 11092 public void setError(String msg, PackageParserException e) { 11093 returnCode = e.error; 11094 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11095 Slog.w(TAG, msg, e); 11096 } 11097 11098 public void setError(String msg, PackageManagerException e) { 11099 returnCode = e.error; 11100 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 11101 Slog.w(TAG, msg, e); 11102 } 11103 11104 // In some error cases we want to convey more info back to the observer 11105 String origPackage; 11106 String origPermission; 11107 } 11108 11109 /* 11110 * Install a non-existing package. 11111 */ 11112 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 11113 UserHandle user, String installerPackageName, String volumeUuid, 11114 PackageInstalledInfo res) { 11115 // Remember this for later, in case we need to rollback this install 11116 String pkgName = pkg.packageName; 11117 11118 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 11119 final boolean dataDirExists = PackageManager.getDataDirForUser(volumeUuid, pkgName, 11120 UserHandle.USER_OWNER).exists(); 11121 synchronized(mPackages) { 11122 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 11123 // A package with the same name is already installed, though 11124 // it has been renamed to an older name. The package we 11125 // are trying to install should be installed as an update to 11126 // the existing one, but that has not been requested, so bail. 11127 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 11128 + " without first uninstalling package running as " 11129 + mSettings.mRenamedPackages.get(pkgName)); 11130 return; 11131 } 11132 if (mPackages.containsKey(pkgName)) { 11133 // Don't allow installation over an existing package with the same name. 11134 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 11135 + " without first uninstalling."); 11136 return; 11137 } 11138 } 11139 11140 try { 11141 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 11142 System.currentTimeMillis(), user); 11143 11144 updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user); 11145 // delete the partially installed application. the data directory will have to be 11146 // restored if it was already existing 11147 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11148 // remove package from internal structures. Note that we want deletePackageX to 11149 // delete the package data and cache directories that it created in 11150 // scanPackageLocked, unless those directories existed before we even tried to 11151 // install. 11152 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 11153 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 11154 res.removedInfo, true); 11155 } 11156 11157 } catch (PackageManagerException e) { 11158 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11159 } 11160 } 11161 11162 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 11163 // Can't rotate keys during boot or if sharedUser. 11164 if (oldPs == null || (scanFlags&SCAN_BOOTING) != 0 || oldPs.sharedUser != null 11165 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 11166 return false; 11167 } 11168 // app is using upgradeKeySets; make sure all are valid 11169 KeySetManagerService ksms = mSettings.mKeySetManagerService; 11170 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 11171 for (int i = 0; i < upgradeKeySets.length; i++) { 11172 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 11173 Slog.wtf(TAG, "Package " 11174 + (oldPs.name != null ? oldPs.name : "<null>") 11175 + " contains upgrade-key-set reference to unknown key-set: " 11176 + upgradeKeySets[i] 11177 + " reverting to signatures check."); 11178 return false; 11179 } 11180 } 11181 return true; 11182 } 11183 11184 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 11185 // Upgrade keysets are being used. Determine if new package has a superset of the 11186 // required keys. 11187 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 11188 KeySetManagerService ksms = mSettings.mKeySetManagerService; 11189 for (int i = 0; i < upgradeKeySets.length; i++) { 11190 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 11191 if (newPkg.mSigningKeys.containsAll(upgradeSet)) { 11192 return true; 11193 } 11194 } 11195 return false; 11196 } 11197 11198 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 11199 UserHandle user, String installerPackageName, String volumeUuid, 11200 PackageInstalledInfo res) { 11201 final PackageParser.Package oldPackage; 11202 final String pkgName = pkg.packageName; 11203 final int[] allUsers; 11204 final boolean[] perUserInstalled; 11205 final boolean weFroze; 11206 11207 // First find the old package info and check signatures 11208 synchronized(mPackages) { 11209 oldPackage = mPackages.get(pkgName); 11210 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 11211 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11212 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 11213 if(!checkUpgradeKeySetLP(ps, pkg)) { 11214 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 11215 "New package not signed by keys specified by upgrade-keysets: " 11216 + pkgName); 11217 return; 11218 } 11219 } else { 11220 // default to original signature matching 11221 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 11222 != PackageManager.SIGNATURE_MATCH) { 11223 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 11224 "New package has a different signature: " + pkgName); 11225 return; 11226 } 11227 } 11228 11229 // In case of rollback, remember per-user/profile install state 11230 allUsers = sUserManager.getUserIds(); 11231 perUserInstalled = new boolean[allUsers.length]; 11232 for (int i = 0; i < allUsers.length; i++) { 11233 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 11234 } 11235 11236 // Mark the app as frozen to prevent launching during the upgrade 11237 // process, and then kill all running instances 11238 if (!ps.frozen) { 11239 ps.frozen = true; 11240 weFroze = true; 11241 } else { 11242 weFroze = false; 11243 } 11244 } 11245 11246 // Now that we're guarded by frozen state, kill app during upgrade 11247 killApplication(pkgName, oldPackage.applicationInfo.uid, "replace pkg"); 11248 11249 try { 11250 boolean sysPkg = (isSystemApp(oldPackage)); 11251 if (sysPkg) { 11252 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 11253 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 11254 } else { 11255 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 11256 user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); 11257 } 11258 } finally { 11259 // Regardless of success or failure of upgrade steps above, always 11260 // unfreeze the package if we froze it 11261 if (weFroze) { 11262 unfreezePackage(pkgName); 11263 } 11264 } 11265 } 11266 11267 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 11268 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 11269 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 11270 String volumeUuid, PackageInstalledInfo res) { 11271 String pkgName = deletedPackage.packageName; 11272 boolean deletedPkg = true; 11273 boolean updatedSettings = false; 11274 11275 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 11276 + deletedPackage); 11277 long origUpdateTime; 11278 if (pkg.mExtras != null) { 11279 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 11280 } else { 11281 origUpdateTime = 0; 11282 } 11283 11284 // First delete the existing package while retaining the data directory 11285 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 11286 res.removedInfo, true)) { 11287 // If the existing package wasn't successfully deleted 11288 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 11289 deletedPkg = false; 11290 } else { 11291 // Successfully deleted the old package; proceed with replace. 11292 11293 // If deleted package lived in a container, give users a chance to 11294 // relinquish resources before killing. 11295 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 11296 if (DEBUG_INSTALL) { 11297 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 11298 } 11299 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 11300 final ArrayList<String> pkgList = new ArrayList<String>(1); 11301 pkgList.add(deletedPackage.applicationInfo.packageName); 11302 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 11303 } 11304 11305 deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName); 11306 try { 11307 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, 11308 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 11309 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 11310 perUserInstalled, res, user); 11311 updatedSettings = true; 11312 } catch (PackageManagerException e) { 11313 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11314 } 11315 } 11316 11317 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11318 // remove package from internal structures. Note that we want deletePackageX to 11319 // delete the package data and cache directories that it created in 11320 // scanPackageLocked, unless those directories existed before we even tried to 11321 // install. 11322 if(updatedSettings) { 11323 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 11324 deletePackageLI( 11325 pkgName, null, true, allUsers, perUserInstalled, 11326 PackageManager.DELETE_KEEP_DATA, 11327 res.removedInfo, true); 11328 } 11329 // Since we failed to install the new package we need to restore the old 11330 // package that we deleted. 11331 if (deletedPkg) { 11332 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 11333 File restoreFile = new File(deletedPackage.codePath); 11334 // Parse old package 11335 boolean oldExternal = isExternal(deletedPackage); 11336 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 11337 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 11338 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 11339 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 11340 try { 11341 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null); 11342 } catch (PackageManagerException e) { 11343 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 11344 + e.getMessage()); 11345 return; 11346 } 11347 // Restore of old package succeeded. Update permissions. 11348 // writer 11349 synchronized (mPackages) { 11350 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 11351 UPDATE_PERMISSIONS_ALL); 11352 // can downgrade to reader 11353 mSettings.writeLPr(); 11354 } 11355 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 11356 } 11357 } 11358 } 11359 11360 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 11361 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 11362 int[] allUsers, boolean[] perUserInstalled, String installerPackageName, 11363 String volumeUuid, PackageInstalledInfo res) { 11364 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 11365 + ", old=" + deletedPackage); 11366 boolean disabledSystem = false; 11367 boolean updatedSettings = false; 11368 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 11369 if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 11370 != 0) { 11371 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 11372 } 11373 String packageName = deletedPackage.packageName; 11374 if (packageName == null) { 11375 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 11376 "Attempt to delete null packageName."); 11377 return; 11378 } 11379 PackageParser.Package oldPkg; 11380 PackageSetting oldPkgSetting; 11381 // reader 11382 synchronized (mPackages) { 11383 oldPkg = mPackages.get(packageName); 11384 oldPkgSetting = mSettings.mPackages.get(packageName); 11385 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 11386 (oldPkgSetting == null)) { 11387 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 11388 "Couldn't find package:" + packageName + " information"); 11389 return; 11390 } 11391 } 11392 11393 res.removedInfo.uid = oldPkg.applicationInfo.uid; 11394 res.removedInfo.removedPackage = packageName; 11395 // Remove existing system package 11396 removePackageLI(oldPkgSetting, true); 11397 // writer 11398 synchronized (mPackages) { 11399 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 11400 if (!disabledSystem && deletedPackage != null) { 11401 // We didn't need to disable the .apk as a current system package, 11402 // which means we are replacing another update that is already 11403 // installed. We need to make sure to delete the older one's .apk. 11404 res.removedInfo.args = createInstallArgsForExisting(0, 11405 deletedPackage.applicationInfo.getCodePath(), 11406 deletedPackage.applicationInfo.getResourcePath(), 11407 getAppDexInstructionSets(deletedPackage.applicationInfo)); 11408 } else { 11409 res.removedInfo.args = null; 11410 } 11411 } 11412 11413 // Successfully disabled the old package. Now proceed with re-installation 11414 deleteCodeCacheDirsLI(pkg.volumeUuid, packageName); 11415 11416 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11417 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 11418 11419 PackageParser.Package newPackage = null; 11420 try { 11421 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user); 11422 if (newPackage.mExtras != null) { 11423 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 11424 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 11425 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 11426 11427 // is the update attempting to change shared user? that isn't going to work... 11428 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 11429 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 11430 "Forbidding shared user change from " + oldPkgSetting.sharedUser 11431 + " to " + newPkgSetting.sharedUser); 11432 updatedSettings = true; 11433 } 11434 } 11435 11436 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11437 updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers, 11438 perUserInstalled, res, user); 11439 updatedSettings = true; 11440 } 11441 11442 } catch (PackageManagerException e) { 11443 res.setError("Package couldn't be installed in " + pkg.codePath, e); 11444 } 11445 11446 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 11447 // Re installation failed. Restore old information 11448 // Remove new pkg information 11449 if (newPackage != null) { 11450 removeInstalledPackageLI(newPackage, true); 11451 } 11452 // Add back the old system package 11453 try { 11454 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 11455 } catch (PackageManagerException e) { 11456 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 11457 } 11458 // Restore the old system information in Settings 11459 synchronized (mPackages) { 11460 if (disabledSystem) { 11461 mSettings.enableSystemPackageLPw(packageName); 11462 } 11463 if (updatedSettings) { 11464 mSettings.setInstallerPackageName(packageName, 11465 oldPkgSetting.installerPackageName); 11466 } 11467 mSettings.writeLPr(); 11468 } 11469 } 11470 } 11471 11472 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 11473 String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res, 11474 UserHandle user) { 11475 String pkgName = newPackage.packageName; 11476 synchronized (mPackages) { 11477 //write settings. the installStatus will be incomplete at this stage. 11478 //note that the new package setting would have already been 11479 //added to mPackages. It hasn't been persisted yet. 11480 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 11481 mSettings.writeLPr(); 11482 } 11483 11484 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 11485 11486 synchronized (mPackages) { 11487 updatePermissionsLPw(newPackage.packageName, newPackage, 11488 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 11489 ? UPDATE_PERMISSIONS_ALL : 0)); 11490 // For system-bundled packages, we assume that installing an upgraded version 11491 // of the package implies that the user actually wants to run that new code, 11492 // so we enable the package. 11493 PackageSetting ps = mSettings.mPackages.get(pkgName); 11494 if (ps != null) { 11495 if (isSystemApp(newPackage)) { 11496 // NB: implicit assumption that system package upgrades apply to all users 11497 if (DEBUG_INSTALL) { 11498 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 11499 } 11500 if (res.origUsers != null) { 11501 for (int userHandle : res.origUsers) { 11502 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 11503 userHandle, installerPackageName); 11504 } 11505 } 11506 // Also convey the prior install/uninstall state 11507 if (allUsers != null && perUserInstalled != null) { 11508 for (int i = 0; i < allUsers.length; i++) { 11509 if (DEBUG_INSTALL) { 11510 Slog.d(TAG, " user " + allUsers[i] 11511 + " => " + perUserInstalled[i]); 11512 } 11513 ps.setInstalled(perUserInstalled[i], allUsers[i]); 11514 } 11515 // these install state changes will be persisted in the 11516 // upcoming call to mSettings.writeLPr(). 11517 } 11518 } 11519 // It's implied that when a user requests installation, they want the app to be 11520 // installed and enabled. 11521 int userId = user.getIdentifier(); 11522 if (userId != UserHandle.USER_ALL) { 11523 ps.setInstalled(true, userId); 11524 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 11525 } 11526 } 11527 res.name = pkgName; 11528 res.uid = newPackage.applicationInfo.uid; 11529 res.pkg = newPackage; 11530 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 11531 mSettings.setInstallerPackageName(pkgName, installerPackageName); 11532 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11533 //to update install status 11534 mSettings.writeLPr(); 11535 } 11536 } 11537 11538 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 11539 final int installFlags = args.installFlags; 11540 final String installerPackageName = args.installerPackageName; 11541 final String volumeUuid = args.volumeUuid; 11542 final File tmpPackageFile = new File(args.getCodePath()); 11543 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 11544 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 11545 || (args.volumeUuid != null)); 11546 boolean replace = false; 11547 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 11548 // Result object to be returned 11549 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 11550 11551 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 11552 // Retrieve PackageSettings and parse package 11553 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 11554 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 11555 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 11556 PackageParser pp = new PackageParser(); 11557 pp.setSeparateProcesses(mSeparateProcesses); 11558 pp.setDisplayMetrics(mMetrics); 11559 11560 final PackageParser.Package pkg; 11561 try { 11562 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 11563 } catch (PackageParserException e) { 11564 res.setError("Failed parse during installPackageLI", e); 11565 return; 11566 } 11567 11568 // Mark that we have an install time CPU ABI override. 11569 pkg.cpuAbiOverride = args.abiOverride; 11570 11571 String pkgName = res.name = pkg.packageName; 11572 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 11573 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 11574 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 11575 return; 11576 } 11577 } 11578 11579 try { 11580 pp.collectCertificates(pkg, parseFlags); 11581 pp.collectManifestDigest(pkg); 11582 } catch (PackageParserException e) { 11583 res.setError("Failed collect during installPackageLI", e); 11584 return; 11585 } 11586 11587 /* If the installer passed in a manifest digest, compare it now. */ 11588 if (args.manifestDigest != null) { 11589 if (DEBUG_INSTALL) { 11590 final String parsedManifest = pkg.manifestDigest == null ? "null" 11591 : pkg.manifestDigest.toString(); 11592 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 11593 + parsedManifest); 11594 } 11595 11596 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 11597 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 11598 return; 11599 } 11600 } else if (DEBUG_INSTALL) { 11601 final String parsedManifest = pkg.manifestDigest == null 11602 ? "null" : pkg.manifestDigest.toString(); 11603 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 11604 } 11605 11606 // Get rid of all references to package scan path via parser. 11607 pp = null; 11608 String oldCodePath = null; 11609 boolean systemApp = false; 11610 synchronized (mPackages) { 11611 // Check if installing already existing package 11612 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11613 String oldName = mSettings.mRenamedPackages.get(pkgName); 11614 if (pkg.mOriginalPackages != null 11615 && pkg.mOriginalPackages.contains(oldName) 11616 && mPackages.containsKey(oldName)) { 11617 // This package is derived from an original package, 11618 // and this device has been updating from that original 11619 // name. We must continue using the original name, so 11620 // rename the new package here. 11621 pkg.setPackageName(oldName); 11622 pkgName = pkg.packageName; 11623 replace = true; 11624 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 11625 + oldName + " pkgName=" + pkgName); 11626 } else if (mPackages.containsKey(pkgName)) { 11627 // This package, under its official name, already exists 11628 // on the device; we should replace it. 11629 replace = true; 11630 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 11631 } 11632 11633 // Prevent apps opting out from runtime permissions 11634 if (replace) { 11635 PackageParser.Package oldPackage = mPackages.get(pkgName); 11636 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 11637 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 11638 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 11639 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 11640 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 11641 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 11642 + " doesn't support runtime permissions but the old" 11643 + " target SDK " + oldTargetSdk + " does."); 11644 return; 11645 } 11646 } 11647 } 11648 11649 PackageSetting ps = mSettings.mPackages.get(pkgName); 11650 if (ps != null) { 11651 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 11652 11653 // Quick sanity check that we're signed correctly if updating; 11654 // we'll check this again later when scanning, but we want to 11655 // bail early here before tripping over redefined permissions. 11656 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 11657 if (!checkUpgradeKeySetLP(ps, pkg)) { 11658 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 11659 + pkg.packageName + " upgrade keys do not match the " 11660 + "previously installed version"); 11661 return; 11662 } 11663 } else { 11664 try { 11665 verifySignaturesLP(ps, pkg); 11666 } catch (PackageManagerException e) { 11667 res.setError(e.error, e.getMessage()); 11668 return; 11669 } 11670 } 11671 11672 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 11673 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 11674 systemApp = (ps.pkg.applicationInfo.flags & 11675 ApplicationInfo.FLAG_SYSTEM) != 0; 11676 } 11677 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11678 } 11679 11680 // Check whether the newly-scanned package wants to define an already-defined perm 11681 int N = pkg.permissions.size(); 11682 for (int i = N-1; i >= 0; i--) { 11683 PackageParser.Permission perm = pkg.permissions.get(i); 11684 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 11685 if (bp != null) { 11686 // If the defining package is signed with our cert, it's okay. This 11687 // also includes the "updating the same package" case, of course. 11688 // "updating same package" could also involve key-rotation. 11689 final boolean sigsOk; 11690 if (bp.sourcePackage.equals(pkg.packageName) 11691 && (bp.packageSetting instanceof PackageSetting) 11692 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 11693 scanFlags))) { 11694 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 11695 } else { 11696 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 11697 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 11698 } 11699 if (!sigsOk) { 11700 // If the owning package is the system itself, we log but allow 11701 // install to proceed; we fail the install on all other permission 11702 // redefinitions. 11703 if (!bp.sourcePackage.equals("android")) { 11704 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 11705 + pkg.packageName + " attempting to redeclare permission " 11706 + perm.info.name + " already owned by " + bp.sourcePackage); 11707 res.origPermission = perm.info.name; 11708 res.origPackage = bp.sourcePackage; 11709 return; 11710 } else { 11711 Slog.w(TAG, "Package " + pkg.packageName 11712 + " attempting to redeclare system permission " 11713 + perm.info.name + "; ignoring new declaration"); 11714 pkg.permissions.remove(i); 11715 } 11716 } 11717 } 11718 } 11719 11720 } 11721 11722 if (systemApp && onExternal) { 11723 // Disable updates to system apps on sdcard 11724 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 11725 "Cannot install updates to system apps on sdcard"); 11726 return; 11727 } 11728 11729 if (args.move != null) { 11730 // We did an in-place move, so dex is ready to roll 11731 scanFlags |= SCAN_NO_DEX; 11732 scanFlags |= SCAN_MOVE; 11733 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 11734 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 11735 scanFlags |= SCAN_NO_DEX; 11736 11737 try { 11738 derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride, 11739 true /* extract libs */); 11740 } catch (PackageManagerException pme) { 11741 Slog.e(TAG, "Error deriving application ABI", pme); 11742 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 11743 return; 11744 } 11745 11746 // Run dexopt before old package gets removed, to minimize time when app is unavailable 11747 int result = mPackageDexOptimizer 11748 .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */, 11749 false /* defer */, false /* inclDependencies */); 11750 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 11751 res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); 11752 return; 11753 } 11754 } 11755 11756 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 11757 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 11758 return; 11759 } 11760 11761 startIntentFilterVerifications(args.user.getIdentifier(), pkg); 11762 11763 if (replace) { 11764 replacePackageLI(pkg, parseFlags, scanFlags, args.user, 11765 installerPackageName, volumeUuid, res); 11766 } else { 11767 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 11768 args.user, installerPackageName, volumeUuid, res); 11769 } 11770 synchronized (mPackages) { 11771 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11772 if (ps != null) { 11773 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 11774 } 11775 } 11776 } 11777 11778 private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) { 11779 if (mIntentFilterVerifierComponent == null) { 11780 Slog.w(TAG, "No IntentFilter verification will not be done as " 11781 + "there is no IntentFilterVerifier available!"); 11782 return; 11783 } 11784 11785 final int verifierUid = getPackageUid( 11786 mIntentFilterVerifierComponent.getPackageName(), 11787 (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId); 11788 11789 mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); 11790 final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 11791 msg.obj = pkg; 11792 msg.arg1 = userId; 11793 msg.arg2 = verifierUid; 11794 11795 mHandler.sendMessage(msg); 11796 } 11797 11798 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, 11799 PackageParser.Package pkg) { 11800 int size = pkg.activities.size(); 11801 if (size == 0) { 11802 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 11803 "No activity, so no need to verify any IntentFilter!"); 11804 return; 11805 } 11806 11807 final boolean hasDomainURLs = hasDomainURLs(pkg); 11808 if (!hasDomainURLs) { 11809 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 11810 "No domain URLs, so no need to verify any IntentFilter!"); 11811 return; 11812 } 11813 11814 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 11815 + " if any IntentFilter from the " + size 11816 + " Activities needs verification ..."); 11817 11818 final int verificationId = mIntentFilterVerificationToken++; 11819 int count = 0; 11820 final String packageName = pkg.packageName; 11821 ArrayList<String> allHosts = new ArrayList<>(); 11822 11823 synchronized (mPackages) { 11824 for (PackageParser.Activity a : pkg.activities) { 11825 for (ActivityIntentInfo filter : a.intents) { 11826 boolean needsFilterVerification = filter.needsVerification(); 11827 if (needsFilterVerification && needsNetworkVerificationLPr(filter)) { 11828 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 11829 "Verification needed for IntentFilter:" + filter.toString()); 11830 mIntentFilterVerifier.addOneIntentFilterVerification( 11831 verifierUid, userId, verificationId, filter, packageName); 11832 count++; 11833 } else if (!needsFilterVerification) { 11834 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 11835 "No verification needed for IntentFilter:" + filter.toString()); 11836 if (hasValidDomains(filter)) { 11837 ArrayList<String> hosts = filter.getHostsList(); 11838 if (hosts.size() > 0) { 11839 allHosts.addAll(hosts); 11840 } else { 11841 if (allHosts.isEmpty()) { 11842 allHosts.add("*"); 11843 } 11844 } 11845 } 11846 } else { 11847 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 11848 "Verification already done for IntentFilter:" + filter.toString()); 11849 } 11850 } 11851 } 11852 } 11853 11854 if (count > 0) { 11855 mIntentFilterVerifier.startVerifications(userId); 11856 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Started " + count 11857 + " IntentFilter verification" + (count > 1 ? "s" : "") 11858 + " for userId:" + userId + "!"); 11859 } else { 11860 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 11861 "No need to start any IntentFilter verification!"); 11862 if (allHosts.size() > 0 && mSettings.createIntentFilterVerificationIfNeededLPw( 11863 packageName, allHosts) != null) { 11864 scheduleWriteSettingsLocked(); 11865 } 11866 } 11867 } 11868 11869 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 11870 final ComponentName cn = filter.activity.getComponentName(); 11871 final String packageName = cn.getPackageName(); 11872 11873 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 11874 packageName); 11875 if (ivi == null) { 11876 return true; 11877 } 11878 int status = ivi.getStatus(); 11879 switch (status) { 11880 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 11881 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 11882 return true; 11883 11884 default: 11885 // Nothing to do 11886 return false; 11887 } 11888 } 11889 11890 private boolean isSystemComponentOrPersistentPrivApp(PackageParser.Package pkg) { 11891 return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID 11892 || ((pkg.applicationInfo.privateFlags 11893 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0 11894 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0); 11895 } 11896 11897 private static boolean isMultiArch(PackageSetting ps) { 11898 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11899 } 11900 11901 private static boolean isMultiArch(ApplicationInfo info) { 11902 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 11903 } 11904 11905 private static boolean isExternal(PackageParser.Package pkg) { 11906 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11907 } 11908 11909 private static boolean isExternal(PackageSetting ps) { 11910 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11911 } 11912 11913 private static boolean isExternal(ApplicationInfo info) { 11914 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 11915 } 11916 11917 private static boolean isSystemApp(PackageParser.Package pkg) { 11918 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11919 } 11920 11921 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 11922 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 11923 } 11924 11925 private static boolean hasDomainURLs(PackageParser.Package pkg) { 11926 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 11927 } 11928 11929 private static boolean isSystemApp(PackageSetting ps) { 11930 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 11931 } 11932 11933 private static boolean isUpdatedSystemApp(PackageSetting ps) { 11934 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 11935 } 11936 11937 private int packageFlagsToInstallFlags(PackageSetting ps) { 11938 int installFlags = 0; 11939 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 11940 // This existing package was an external ASEC install when we have 11941 // the external flag without a UUID 11942 installFlags |= PackageManager.INSTALL_EXTERNAL; 11943 } 11944 if (ps.isForwardLocked()) { 11945 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 11946 } 11947 return installFlags; 11948 } 11949 11950 private void deleteTempPackageFiles() { 11951 final FilenameFilter filter = new FilenameFilter() { 11952 public boolean accept(File dir, String name) { 11953 return name.startsWith("vmdl") && name.endsWith(".tmp"); 11954 } 11955 }; 11956 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 11957 file.delete(); 11958 } 11959 } 11960 11961 @Override 11962 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 11963 int flags) { 11964 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 11965 flags); 11966 } 11967 11968 @Override 11969 public void deletePackage(final String packageName, 11970 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 11971 mContext.enforceCallingOrSelfPermission( 11972 android.Manifest.permission.DELETE_PACKAGES, null); 11973 final int uid = Binder.getCallingUid(); 11974 if (UserHandle.getUserId(uid) != userId) { 11975 mContext.enforceCallingPermission( 11976 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 11977 "deletePackage for user " + userId); 11978 } 11979 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 11980 try { 11981 observer.onPackageDeleted(packageName, 11982 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 11983 } catch (RemoteException re) { 11984 } 11985 return; 11986 } 11987 11988 boolean uninstallBlocked = false; 11989 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 11990 int[] users = sUserManager.getUserIds(); 11991 for (int i = 0; i < users.length; ++i) { 11992 if (getBlockUninstallForUser(packageName, users[i])) { 11993 uninstallBlocked = true; 11994 break; 11995 } 11996 } 11997 } else { 11998 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 11999 } 12000 if (uninstallBlocked) { 12001 try { 12002 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 12003 null); 12004 } catch (RemoteException re) { 12005 } 12006 return; 12007 } 12008 12009 if (DEBUG_REMOVE) { 12010 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 12011 } 12012 // Queue up an async operation since the package deletion may take a little while. 12013 mHandler.post(new Runnable() { 12014 public void run() { 12015 mHandler.removeCallbacks(this); 12016 final int returnCode = deletePackageX(packageName, userId, flags); 12017 if (observer != null) { 12018 try { 12019 observer.onPackageDeleted(packageName, returnCode, null); 12020 } catch (RemoteException e) { 12021 Log.i(TAG, "Observer no longer exists."); 12022 } //end catch 12023 } //end if 12024 } //end run 12025 }); 12026 } 12027 12028 private boolean isPackageDeviceAdmin(String packageName, int userId) { 12029 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 12030 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 12031 try { 12032 if (dpm != null) { 12033 if (dpm.isDeviceOwner(packageName)) { 12034 return true; 12035 } 12036 int[] users; 12037 if (userId == UserHandle.USER_ALL) { 12038 users = sUserManager.getUserIds(); 12039 } else { 12040 users = new int[]{userId}; 12041 } 12042 for (int i = 0; i < users.length; ++i) { 12043 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 12044 return true; 12045 } 12046 } 12047 } 12048 } catch (RemoteException e) { 12049 } 12050 return false; 12051 } 12052 12053 /** 12054 * This method is an internal method that could be get invoked either 12055 * to delete an installed package or to clean up a failed installation. 12056 * After deleting an installed package, a broadcast is sent to notify any 12057 * listeners that the package has been installed. For cleaning up a failed 12058 * installation, the broadcast is not necessary since the package's 12059 * installation wouldn't have sent the initial broadcast either 12060 * The key steps in deleting a package are 12061 * deleting the package information in internal structures like mPackages, 12062 * deleting the packages base directories through installd 12063 * updating mSettings to reflect current status 12064 * persisting settings for later use 12065 * sending a broadcast if necessary 12066 */ 12067 private int deletePackageX(String packageName, int userId, int flags) { 12068 final PackageRemovedInfo info = new PackageRemovedInfo(); 12069 final boolean res; 12070 12071 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 12072 ? UserHandle.ALL : new UserHandle(userId); 12073 12074 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 12075 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 12076 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 12077 } 12078 12079 boolean removedForAllUsers = false; 12080 boolean systemUpdate = false; 12081 12082 // for the uninstall-updates case and restricted profiles, remember the per- 12083 // userhandle installed state 12084 int[] allUsers; 12085 boolean[] perUserInstalled; 12086 synchronized (mPackages) { 12087 PackageSetting ps = mSettings.mPackages.get(packageName); 12088 allUsers = sUserManager.getUserIds(); 12089 perUserInstalled = new boolean[allUsers.length]; 12090 for (int i = 0; i < allUsers.length; i++) { 12091 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 12092 } 12093 } 12094 12095 synchronized (mInstallLock) { 12096 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 12097 res = deletePackageLI(packageName, removeForUser, 12098 true, allUsers, perUserInstalled, 12099 flags | REMOVE_CHATTY, info, true); 12100 systemUpdate = info.isRemovedPackageSystemUpdate; 12101 if (res && !systemUpdate && mPackages.get(packageName) == null) { 12102 removedForAllUsers = true; 12103 } 12104 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 12105 + " removedForAllUsers=" + removedForAllUsers); 12106 } 12107 12108 if (res) { 12109 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 12110 12111 // If the removed package was a system update, the old system package 12112 // was re-enabled; we need to broadcast this information 12113 if (systemUpdate) { 12114 Bundle extras = new Bundle(1); 12115 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 12116 ? info.removedAppId : info.uid); 12117 extras.putBoolean(Intent.EXTRA_REPLACING, true); 12118 12119 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 12120 extras, null, null, null); 12121 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 12122 extras, null, null, null); 12123 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 12124 null, packageName, null, null); 12125 } 12126 } 12127 // Force a gc here. 12128 Runtime.getRuntime().gc(); 12129 // Delete the resources here after sending the broadcast to let 12130 // other processes clean up before deleting resources. 12131 if (info.args != null) { 12132 synchronized (mInstallLock) { 12133 info.args.doPostDeleteLI(true); 12134 } 12135 } 12136 12137 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 12138 } 12139 12140 class PackageRemovedInfo { 12141 String removedPackage; 12142 int uid = -1; 12143 int removedAppId = -1; 12144 int[] removedUsers = null; 12145 boolean isRemovedPackageSystemUpdate = false; 12146 // Clean up resources deleted packages. 12147 InstallArgs args = null; 12148 12149 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 12150 Bundle extras = new Bundle(1); 12151 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 12152 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 12153 if (replacing) { 12154 extras.putBoolean(Intent.EXTRA_REPLACING, true); 12155 } 12156 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 12157 if (removedPackage != null) { 12158 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 12159 extras, null, null, removedUsers); 12160 if (fullRemove && !replacing) { 12161 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 12162 extras, null, null, removedUsers); 12163 } 12164 } 12165 if (removedAppId >= 0) { 12166 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 12167 removedUsers); 12168 } 12169 } 12170 } 12171 12172 /* 12173 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 12174 * flag is not set, the data directory is removed as well. 12175 * make sure this flag is set for partially installed apps. If not its meaningless to 12176 * delete a partially installed application. 12177 */ 12178 private void removePackageDataLI(PackageSetting ps, 12179 int[] allUserHandles, boolean[] perUserInstalled, 12180 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 12181 String packageName = ps.name; 12182 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 12183 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 12184 // Retrieve object to delete permissions for shared user later on 12185 final PackageSetting deletedPs; 12186 // reader 12187 synchronized (mPackages) { 12188 deletedPs = mSettings.mPackages.get(packageName); 12189 if (outInfo != null) { 12190 outInfo.removedPackage = packageName; 12191 outInfo.removedUsers = deletedPs != null 12192 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 12193 : null; 12194 } 12195 } 12196 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 12197 removeDataDirsLI(ps.volumeUuid, packageName); 12198 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 12199 } 12200 // writer 12201 synchronized (mPackages) { 12202 if (deletedPs != null) { 12203 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 12204 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 12205 clearDefaultBrowserIfNeeded(packageName); 12206 if (outInfo != null) { 12207 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 12208 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 12209 } 12210 updatePermissionsLPw(deletedPs.name, null, 0); 12211 if (deletedPs.sharedUser != null) { 12212 // Remove permissions associated with package. Since runtime 12213 // permissions are per user we have to kill the removed package 12214 // or packages running under the shared user of the removed 12215 // package if revoking the permissions requested only by the removed 12216 // package is successful and this causes a change in gids. 12217 for (int userId : UserManagerService.getInstance().getUserIds()) { 12218 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 12219 userId); 12220 if (userIdToKill == UserHandle.USER_ALL 12221 || userIdToKill >= UserHandle.USER_OWNER) { 12222 // If gids changed for this user, kill all affected packages. 12223 mHandler.post(new Runnable() { 12224 @Override 12225 public void run() { 12226 // This has to happen with no lock held. 12227 killSettingPackagesForUser(deletedPs, userIdToKill, 12228 KILL_APP_REASON_GIDS_CHANGED); 12229 } 12230 }); 12231 break; 12232 } 12233 } 12234 } 12235 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 12236 } 12237 // make sure to preserve per-user disabled state if this removal was just 12238 // a downgrade of a system app to the factory package 12239 if (allUserHandles != null && perUserInstalled != null) { 12240 if (DEBUG_REMOVE) { 12241 Slog.d(TAG, "Propagating install state across downgrade"); 12242 } 12243 for (int i = 0; i < allUserHandles.length; i++) { 12244 if (DEBUG_REMOVE) { 12245 Slog.d(TAG, " user " + allUserHandles[i] 12246 + " => " + perUserInstalled[i]); 12247 } 12248 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 12249 } 12250 } 12251 } 12252 // can downgrade to reader 12253 if (writeSettings) { 12254 // Save settings now 12255 mSettings.writeLPr(); 12256 } 12257 } 12258 if (outInfo != null) { 12259 // A user ID was deleted here. Go through all users and remove it 12260 // from KeyStore. 12261 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 12262 } 12263 } 12264 12265 static boolean locationIsPrivileged(File path) { 12266 try { 12267 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 12268 .getCanonicalPath(); 12269 return path.getCanonicalPath().startsWith(privilegedAppDir); 12270 } catch (IOException e) { 12271 Slog.e(TAG, "Unable to access code path " + path); 12272 } 12273 return false; 12274 } 12275 12276 /* 12277 * Tries to delete system package. 12278 */ 12279 private boolean deleteSystemPackageLI(PackageSetting newPs, 12280 int[] allUserHandles, boolean[] perUserInstalled, 12281 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 12282 final boolean applyUserRestrictions 12283 = (allUserHandles != null) && (perUserInstalled != null); 12284 PackageSetting disabledPs = null; 12285 // Confirm if the system package has been updated 12286 // An updated system app can be deleted. This will also have to restore 12287 // the system pkg from system partition 12288 // reader 12289 synchronized (mPackages) { 12290 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 12291 } 12292 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 12293 + " disabledPs=" + disabledPs); 12294 if (disabledPs == null) { 12295 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 12296 return false; 12297 } else if (DEBUG_REMOVE) { 12298 Slog.d(TAG, "Deleting system pkg from data partition"); 12299 } 12300 if (DEBUG_REMOVE) { 12301 if (applyUserRestrictions) { 12302 Slog.d(TAG, "Remembering install states:"); 12303 for (int i = 0; i < allUserHandles.length; i++) { 12304 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 12305 } 12306 } 12307 } 12308 // Delete the updated package 12309 outInfo.isRemovedPackageSystemUpdate = true; 12310 if (disabledPs.versionCode < newPs.versionCode) { 12311 // Delete data for downgrades 12312 flags &= ~PackageManager.DELETE_KEEP_DATA; 12313 } else { 12314 // Preserve data by setting flag 12315 flags |= PackageManager.DELETE_KEEP_DATA; 12316 } 12317 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 12318 allUserHandles, perUserInstalled, outInfo, writeSettings); 12319 if (!ret) { 12320 return false; 12321 } 12322 // writer 12323 synchronized (mPackages) { 12324 // Reinstate the old system package 12325 mSettings.enableSystemPackageLPw(newPs.name); 12326 // Remove any native libraries from the upgraded package. 12327 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 12328 } 12329 // Install the system package 12330 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 12331 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 12332 if (locationIsPrivileged(disabledPs.codePath)) { 12333 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 12334 } 12335 12336 final PackageParser.Package newPkg; 12337 try { 12338 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 12339 } catch (PackageManagerException e) { 12340 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 12341 return false; 12342 } 12343 12344 // writer 12345 synchronized (mPackages) { 12346 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 12347 updatePermissionsLPw(newPkg.packageName, newPkg, 12348 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 12349 if (applyUserRestrictions) { 12350 if (DEBUG_REMOVE) { 12351 Slog.d(TAG, "Propagating install state across reinstall"); 12352 } 12353 for (int i = 0; i < allUserHandles.length; i++) { 12354 if (DEBUG_REMOVE) { 12355 Slog.d(TAG, " user " + allUserHandles[i] 12356 + " => " + perUserInstalled[i]); 12357 } 12358 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 12359 } 12360 // Regardless of writeSettings we need to ensure that this restriction 12361 // state propagation is persisted 12362 mSettings.writeAllUsersPackageRestrictionsLPr(); 12363 } 12364 // can downgrade to reader here 12365 if (writeSettings) { 12366 mSettings.writeLPr(); 12367 } 12368 } 12369 return true; 12370 } 12371 12372 private boolean deleteInstalledPackageLI(PackageSetting ps, 12373 boolean deleteCodeAndResources, int flags, 12374 int[] allUserHandles, boolean[] perUserInstalled, 12375 PackageRemovedInfo outInfo, boolean writeSettings) { 12376 if (outInfo != null) { 12377 outInfo.uid = ps.appId; 12378 } 12379 12380 // Delete package data from internal structures and also remove data if flag is set 12381 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 12382 12383 // Delete application code and resources 12384 if (deleteCodeAndResources && (outInfo != null)) { 12385 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 12386 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 12387 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 12388 } 12389 return true; 12390 } 12391 12392 @Override 12393 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 12394 int userId) { 12395 mContext.enforceCallingOrSelfPermission( 12396 android.Manifest.permission.DELETE_PACKAGES, null); 12397 synchronized (mPackages) { 12398 PackageSetting ps = mSettings.mPackages.get(packageName); 12399 if (ps == null) { 12400 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 12401 return false; 12402 } 12403 if (!ps.getInstalled(userId)) { 12404 // Can't block uninstall for an app that is not installed or enabled. 12405 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 12406 return false; 12407 } 12408 ps.setBlockUninstall(blockUninstall, userId); 12409 mSettings.writePackageRestrictionsLPr(userId); 12410 } 12411 return true; 12412 } 12413 12414 @Override 12415 public boolean getBlockUninstallForUser(String packageName, int userId) { 12416 synchronized (mPackages) { 12417 PackageSetting ps = mSettings.mPackages.get(packageName); 12418 if (ps == null) { 12419 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 12420 return false; 12421 } 12422 return ps.getBlockUninstall(userId); 12423 } 12424 } 12425 12426 /* 12427 * This method handles package deletion in general 12428 */ 12429 private boolean deletePackageLI(String packageName, UserHandle user, 12430 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 12431 int flags, PackageRemovedInfo outInfo, 12432 boolean writeSettings) { 12433 if (packageName == null) { 12434 Slog.w(TAG, "Attempt to delete null packageName."); 12435 return false; 12436 } 12437 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 12438 PackageSetting ps; 12439 boolean dataOnly = false; 12440 int removeUser = -1; 12441 int appId = -1; 12442 synchronized (mPackages) { 12443 ps = mSettings.mPackages.get(packageName); 12444 if (ps == null) { 12445 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 12446 return false; 12447 } 12448 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 12449 && user.getIdentifier() != UserHandle.USER_ALL) { 12450 // The caller is asking that the package only be deleted for a single 12451 // user. To do this, we just mark its uninstalled state and delete 12452 // its data. If this is a system app, we only allow this to happen if 12453 // they have set the special DELETE_SYSTEM_APP which requests different 12454 // semantics than normal for uninstalling system apps. 12455 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 12456 ps.setUserState(user.getIdentifier(), 12457 COMPONENT_ENABLED_STATE_DEFAULT, 12458 false, //installed 12459 true, //stopped 12460 true, //notLaunched 12461 false, //hidden 12462 null, null, null, 12463 false, // blockUninstall 12464 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 12465 if (!isSystemApp(ps)) { 12466 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 12467 // Other user still have this package installed, so all 12468 // we need to do is clear this user's data and save that 12469 // it is uninstalled. 12470 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 12471 removeUser = user.getIdentifier(); 12472 appId = ps.appId; 12473 scheduleWritePackageRestrictionsLocked(removeUser); 12474 } else { 12475 // We need to set it back to 'installed' so the uninstall 12476 // broadcasts will be sent correctly. 12477 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 12478 ps.setInstalled(true, user.getIdentifier()); 12479 } 12480 } else { 12481 // This is a system app, so we assume that the 12482 // other users still have this package installed, so all 12483 // we need to do is clear this user's data and save that 12484 // it is uninstalled. 12485 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 12486 removeUser = user.getIdentifier(); 12487 appId = ps.appId; 12488 scheduleWritePackageRestrictionsLocked(removeUser); 12489 } 12490 } 12491 } 12492 12493 if (removeUser >= 0) { 12494 // From above, we determined that we are deleting this only 12495 // for a single user. Continue the work here. 12496 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 12497 if (outInfo != null) { 12498 outInfo.removedPackage = packageName; 12499 outInfo.removedAppId = appId; 12500 outInfo.removedUsers = new int[] {removeUser}; 12501 } 12502 mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser); 12503 removeKeystoreDataIfNeeded(removeUser, appId); 12504 schedulePackageCleaning(packageName, removeUser, false); 12505 synchronized (mPackages) { 12506 if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { 12507 scheduleWritePackageRestrictionsLocked(removeUser); 12508 } 12509 } 12510 return true; 12511 } 12512 12513 if (dataOnly) { 12514 // Delete application data first 12515 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 12516 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 12517 return true; 12518 } 12519 12520 boolean ret = false; 12521 if (isSystemApp(ps)) { 12522 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 12523 // When an updated system application is deleted we delete the existing resources as well and 12524 // fall back to existing code in system partition 12525 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 12526 flags, outInfo, writeSettings); 12527 } else { 12528 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 12529 // Kill application pre-emptively especially for apps on sd. 12530 killApplication(packageName, ps.appId, "uninstall pkg"); 12531 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 12532 allUserHandles, perUserInstalled, 12533 outInfo, writeSettings); 12534 } 12535 12536 return ret; 12537 } 12538 12539 private final class ClearStorageConnection implements ServiceConnection { 12540 IMediaContainerService mContainerService; 12541 12542 @Override 12543 public void onServiceConnected(ComponentName name, IBinder service) { 12544 synchronized (this) { 12545 mContainerService = IMediaContainerService.Stub.asInterface(service); 12546 notifyAll(); 12547 } 12548 } 12549 12550 @Override 12551 public void onServiceDisconnected(ComponentName name) { 12552 } 12553 } 12554 12555 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 12556 final boolean mounted; 12557 if (Environment.isExternalStorageEmulated()) { 12558 mounted = true; 12559 } else { 12560 final String status = Environment.getExternalStorageState(); 12561 12562 mounted = status.equals(Environment.MEDIA_MOUNTED) 12563 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 12564 } 12565 12566 if (!mounted) { 12567 return; 12568 } 12569 12570 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 12571 int[] users; 12572 if (userId == UserHandle.USER_ALL) { 12573 users = sUserManager.getUserIds(); 12574 } else { 12575 users = new int[] { userId }; 12576 } 12577 final ClearStorageConnection conn = new ClearStorageConnection(); 12578 if (mContext.bindServiceAsUser( 12579 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 12580 try { 12581 for (int curUser : users) { 12582 long timeout = SystemClock.uptimeMillis() + 5000; 12583 synchronized (conn) { 12584 long now = SystemClock.uptimeMillis(); 12585 while (conn.mContainerService == null && now < timeout) { 12586 try { 12587 conn.wait(timeout - now); 12588 } catch (InterruptedException e) { 12589 } 12590 } 12591 } 12592 if (conn.mContainerService == null) { 12593 return; 12594 } 12595 12596 final UserEnvironment userEnv = new UserEnvironment(curUser); 12597 clearDirectory(conn.mContainerService, 12598 userEnv.buildExternalStorageAppCacheDirs(packageName)); 12599 if (allData) { 12600 clearDirectory(conn.mContainerService, 12601 userEnv.buildExternalStorageAppDataDirs(packageName)); 12602 clearDirectory(conn.mContainerService, 12603 userEnv.buildExternalStorageAppMediaDirs(packageName)); 12604 } 12605 } 12606 } finally { 12607 mContext.unbindService(conn); 12608 } 12609 } 12610 } 12611 12612 @Override 12613 public void clearApplicationUserData(final String packageName, 12614 final IPackageDataObserver observer, final int userId) { 12615 mContext.enforceCallingOrSelfPermission( 12616 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 12617 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 12618 // Queue up an async operation since the package deletion may take a little while. 12619 mHandler.post(new Runnable() { 12620 public void run() { 12621 mHandler.removeCallbacks(this); 12622 final boolean succeeded; 12623 synchronized (mInstallLock) { 12624 succeeded = clearApplicationUserDataLI(packageName, userId); 12625 } 12626 clearExternalStorageDataSync(packageName, userId, true); 12627 if (succeeded) { 12628 // invoke DeviceStorageMonitor's update method to clear any notifications 12629 DeviceStorageMonitorInternal 12630 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 12631 if (dsm != null) { 12632 dsm.checkMemory(); 12633 } 12634 } 12635 if(observer != null) { 12636 try { 12637 observer.onRemoveCompleted(packageName, succeeded); 12638 } catch (RemoteException e) { 12639 Log.i(TAG, "Observer no longer exists."); 12640 } 12641 } //end if observer 12642 } //end run 12643 }); 12644 } 12645 12646 private boolean clearApplicationUserDataLI(String packageName, int userId) { 12647 if (packageName == null) { 12648 Slog.w(TAG, "Attempt to delete null packageName."); 12649 return false; 12650 } 12651 12652 // Try finding details about the requested package 12653 PackageParser.Package pkg; 12654 synchronized (mPackages) { 12655 pkg = mPackages.get(packageName); 12656 if (pkg == null) { 12657 final PackageSetting ps = mSettings.mPackages.get(packageName); 12658 if (ps != null) { 12659 pkg = ps.pkg; 12660 } 12661 } 12662 12663 if (pkg == null) { 12664 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 12665 return false; 12666 } 12667 12668 PackageSetting ps = (PackageSetting) pkg.mExtras; 12669 PermissionsState permissionsState = ps.getPermissionsState(); 12670 revokeRuntimePermissionsAndClearUserSetFlagsLocked(permissionsState, userId); 12671 } 12672 12673 // Always delete data directories for package, even if we found no other 12674 // record of app. This helps users recover from UID mismatches without 12675 // resorting to a full data wipe. 12676 int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId); 12677 if (retCode < 0) { 12678 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 12679 return false; 12680 } 12681 12682 final int appId = pkg.applicationInfo.uid; 12683 removeKeystoreDataIfNeeded(userId, appId); 12684 12685 // Create a native library symlink only if we have native libraries 12686 // and if the native libraries are 32 bit libraries. We do not provide 12687 // this symlink for 64 bit libraries. 12688 if (pkg.applicationInfo.primaryCpuAbi != null && 12689 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 12690 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 12691 if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 12692 nativeLibPath, userId) < 0) { 12693 Slog.w(TAG, "Failed linking native library dir"); 12694 return false; 12695 } 12696 } 12697 12698 return true; 12699 } 12700 12701 12702 /** 12703 * Revokes granted runtime permissions and clears resettable flags 12704 * which are flags that can be set by a user interaction. 12705 * 12706 * @param permissionsState The permission state to reset. 12707 * @param userId The device user for which to do a reset. 12708 */ 12709 private void revokeRuntimePermissionsAndClearUserSetFlagsLocked( 12710 PermissionsState permissionsState, int userId) { 12711 final int userSetFlags = PackageManager.FLAG_PERMISSION_USER_SET 12712 | PackageManager.FLAG_PERMISSION_USER_FIXED 12713 | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 12714 12715 boolean needsWrite = false; 12716 12717 for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) { 12718 BasePermission bp = mSettings.mPermissions.get(state.getName()); 12719 if (bp != null) { 12720 permissionsState.revokeRuntimePermission(bp, userId); 12721 permissionsState.updatePermissionFlags(bp, userId, userSetFlags, 0); 12722 needsWrite = true; 12723 } 12724 } 12725 12726 if (needsWrite) { 12727 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 12728 } 12729 } 12730 12731 /** 12732 * Remove entries from the keystore daemon. Will only remove it if the 12733 * {@code appId} is valid. 12734 */ 12735 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 12736 if (appId < 0) { 12737 return; 12738 } 12739 12740 final KeyStore keyStore = KeyStore.getInstance(); 12741 if (keyStore != null) { 12742 if (userId == UserHandle.USER_ALL) { 12743 for (final int individual : sUserManager.getUserIds()) { 12744 keyStore.clearUid(UserHandle.getUid(individual, appId)); 12745 } 12746 } else { 12747 keyStore.clearUid(UserHandle.getUid(userId, appId)); 12748 } 12749 } else { 12750 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 12751 } 12752 } 12753 12754 @Override 12755 public void deleteApplicationCacheFiles(final String packageName, 12756 final IPackageDataObserver observer) { 12757 mContext.enforceCallingOrSelfPermission( 12758 android.Manifest.permission.DELETE_CACHE_FILES, null); 12759 // Queue up an async operation since the package deletion may take a little while. 12760 final int userId = UserHandle.getCallingUserId(); 12761 mHandler.post(new Runnable() { 12762 public void run() { 12763 mHandler.removeCallbacks(this); 12764 final boolean succeded; 12765 synchronized (mInstallLock) { 12766 succeded = deleteApplicationCacheFilesLI(packageName, userId); 12767 } 12768 clearExternalStorageDataSync(packageName, userId, false); 12769 if (observer != null) { 12770 try { 12771 observer.onRemoveCompleted(packageName, succeded); 12772 } catch (RemoteException e) { 12773 Log.i(TAG, "Observer no longer exists."); 12774 } 12775 } //end if observer 12776 } //end run 12777 }); 12778 } 12779 12780 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 12781 if (packageName == null) { 12782 Slog.w(TAG, "Attempt to delete null packageName."); 12783 return false; 12784 } 12785 PackageParser.Package p; 12786 synchronized (mPackages) { 12787 p = mPackages.get(packageName); 12788 } 12789 if (p == null) { 12790 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12791 return false; 12792 } 12793 final ApplicationInfo applicationInfo = p.applicationInfo; 12794 if (applicationInfo == null) { 12795 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12796 return false; 12797 } 12798 int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId); 12799 if (retCode < 0) { 12800 Slog.w(TAG, "Couldn't remove cache files for package: " 12801 + packageName + " u" + userId); 12802 return false; 12803 } 12804 return true; 12805 } 12806 12807 @Override 12808 public void getPackageSizeInfo(final String packageName, int userHandle, 12809 final IPackageStatsObserver observer) { 12810 mContext.enforceCallingOrSelfPermission( 12811 android.Manifest.permission.GET_PACKAGE_SIZE, null); 12812 if (packageName == null) { 12813 throw new IllegalArgumentException("Attempt to get size of null packageName"); 12814 } 12815 12816 PackageStats stats = new PackageStats(packageName, userHandle); 12817 12818 /* 12819 * Queue up an async operation since the package measurement may take a 12820 * little while. 12821 */ 12822 Message msg = mHandler.obtainMessage(INIT_COPY); 12823 msg.obj = new MeasureParams(stats, observer); 12824 mHandler.sendMessage(msg); 12825 } 12826 12827 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 12828 PackageStats pStats) { 12829 if (packageName == null) { 12830 Slog.w(TAG, "Attempt to get size of null packageName."); 12831 return false; 12832 } 12833 PackageParser.Package p; 12834 boolean dataOnly = false; 12835 String libDirRoot = null; 12836 String asecPath = null; 12837 PackageSetting ps = null; 12838 synchronized (mPackages) { 12839 p = mPackages.get(packageName); 12840 ps = mSettings.mPackages.get(packageName); 12841 if(p == null) { 12842 dataOnly = true; 12843 if((ps == null) || (ps.pkg == null)) { 12844 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 12845 return false; 12846 } 12847 p = ps.pkg; 12848 } 12849 if (ps != null) { 12850 libDirRoot = ps.legacyNativeLibraryPathString; 12851 } 12852 if (p != null && (isExternal(p) || p.isForwardLocked())) { 12853 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 12854 if (secureContainerId != null) { 12855 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 12856 } 12857 } 12858 } 12859 String publicSrcDir = null; 12860 if(!dataOnly) { 12861 final ApplicationInfo applicationInfo = p.applicationInfo; 12862 if (applicationInfo == null) { 12863 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 12864 return false; 12865 } 12866 if (p.isForwardLocked()) { 12867 publicSrcDir = applicationInfo.getBaseResourcePath(); 12868 } 12869 } 12870 // TODO: extend to measure size of split APKs 12871 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 12872 // not just the first level. 12873 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 12874 // just the primary. 12875 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 12876 int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath, 12877 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 12878 if (res < 0) { 12879 return false; 12880 } 12881 12882 // Fix-up for forward-locked applications in ASEC containers. 12883 if (!isExternal(p)) { 12884 pStats.codeSize += pStats.externalCodeSize; 12885 pStats.externalCodeSize = 0L; 12886 } 12887 12888 return true; 12889 } 12890 12891 12892 @Override 12893 public void addPackageToPreferred(String packageName) { 12894 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 12895 } 12896 12897 @Override 12898 public void removePackageFromPreferred(String packageName) { 12899 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 12900 } 12901 12902 @Override 12903 public List<PackageInfo> getPreferredPackages(int flags) { 12904 return new ArrayList<PackageInfo>(); 12905 } 12906 12907 private int getUidTargetSdkVersionLockedLPr(int uid) { 12908 Object obj = mSettings.getUserIdLPr(uid); 12909 if (obj instanceof SharedUserSetting) { 12910 final SharedUserSetting sus = (SharedUserSetting) obj; 12911 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 12912 final Iterator<PackageSetting> it = sus.packages.iterator(); 12913 while (it.hasNext()) { 12914 final PackageSetting ps = it.next(); 12915 if (ps.pkg != null) { 12916 int v = ps.pkg.applicationInfo.targetSdkVersion; 12917 if (v < vers) vers = v; 12918 } 12919 } 12920 return vers; 12921 } else if (obj instanceof PackageSetting) { 12922 final PackageSetting ps = (PackageSetting) obj; 12923 if (ps.pkg != null) { 12924 return ps.pkg.applicationInfo.targetSdkVersion; 12925 } 12926 } 12927 return Build.VERSION_CODES.CUR_DEVELOPMENT; 12928 } 12929 12930 @Override 12931 public void addPreferredActivity(IntentFilter filter, int match, 12932 ComponentName[] set, ComponentName activity, int userId) { 12933 addPreferredActivityInternal(filter, match, set, activity, true, userId, 12934 "Adding preferred"); 12935 } 12936 12937 private void addPreferredActivityInternal(IntentFilter filter, int match, 12938 ComponentName[] set, ComponentName activity, boolean always, int userId, 12939 String opname) { 12940 // writer 12941 int callingUid = Binder.getCallingUid(); 12942 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 12943 if (filter.countActions() == 0) { 12944 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 12945 return; 12946 } 12947 synchronized (mPackages) { 12948 if (mContext.checkCallingOrSelfPermission( 12949 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12950 != PackageManager.PERMISSION_GRANTED) { 12951 if (getUidTargetSdkVersionLockedLPr(callingUid) 12952 < Build.VERSION_CODES.FROYO) { 12953 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 12954 + callingUid); 12955 return; 12956 } 12957 mContext.enforceCallingOrSelfPermission( 12958 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12959 } 12960 12961 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 12962 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 12963 + userId + ":"); 12964 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 12965 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 12966 scheduleWritePackageRestrictionsLocked(userId); 12967 } 12968 } 12969 12970 @Override 12971 public void replacePreferredActivity(IntentFilter filter, int match, 12972 ComponentName[] set, ComponentName activity, int userId) { 12973 if (filter.countActions() != 1) { 12974 throw new IllegalArgumentException( 12975 "replacePreferredActivity expects filter to have only 1 action."); 12976 } 12977 if (filter.countDataAuthorities() != 0 12978 || filter.countDataPaths() != 0 12979 || filter.countDataSchemes() > 1 12980 || filter.countDataTypes() != 0) { 12981 throw new IllegalArgumentException( 12982 "replacePreferredActivity expects filter to have no data authorities, " + 12983 "paths, or types; and at most one scheme."); 12984 } 12985 12986 final int callingUid = Binder.getCallingUid(); 12987 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 12988 synchronized (mPackages) { 12989 if (mContext.checkCallingOrSelfPermission( 12990 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 12991 != PackageManager.PERMISSION_GRANTED) { 12992 if (getUidTargetSdkVersionLockedLPr(callingUid) 12993 < Build.VERSION_CODES.FROYO) { 12994 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 12995 + Binder.getCallingUid()); 12996 return; 12997 } 12998 mContext.enforceCallingOrSelfPermission( 12999 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13000 } 13001 13002 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 13003 if (pir != null) { 13004 // Get all of the existing entries that exactly match this filter. 13005 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 13006 if (existing != null && existing.size() == 1) { 13007 PreferredActivity cur = existing.get(0); 13008 if (DEBUG_PREFERRED) { 13009 Slog.i(TAG, "Checking replace of preferred:"); 13010 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13011 if (!cur.mPref.mAlways) { 13012 Slog.i(TAG, " -- CUR; not mAlways!"); 13013 } else { 13014 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 13015 Slog.i(TAG, " -- CUR: mSet=" 13016 + Arrays.toString(cur.mPref.mSetComponents)); 13017 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 13018 Slog.i(TAG, " -- NEW: mMatch=" 13019 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 13020 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 13021 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 13022 } 13023 } 13024 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 13025 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 13026 && cur.mPref.sameSet(set)) { 13027 // Setting the preferred activity to what it happens to be already 13028 if (DEBUG_PREFERRED) { 13029 Slog.i(TAG, "Replacing with same preferred activity " 13030 + cur.mPref.mShortComponent + " for user " 13031 + userId + ":"); 13032 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13033 } 13034 return; 13035 } 13036 } 13037 13038 if (existing != null) { 13039 if (DEBUG_PREFERRED) { 13040 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 13041 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13042 } 13043 for (int i = 0; i < existing.size(); i++) { 13044 PreferredActivity pa = existing.get(i); 13045 if (DEBUG_PREFERRED) { 13046 Slog.i(TAG, "Removing existing preferred activity " 13047 + pa.mPref.mComponent + ":"); 13048 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 13049 } 13050 pir.removeFilter(pa); 13051 } 13052 } 13053 } 13054 addPreferredActivityInternal(filter, match, set, activity, true, userId, 13055 "Replacing preferred"); 13056 } 13057 } 13058 13059 @Override 13060 public void clearPackagePreferredActivities(String packageName) { 13061 final int uid = Binder.getCallingUid(); 13062 // writer 13063 synchronized (mPackages) { 13064 PackageParser.Package pkg = mPackages.get(packageName); 13065 if (pkg == null || pkg.applicationInfo.uid != uid) { 13066 if (mContext.checkCallingOrSelfPermission( 13067 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 13068 != PackageManager.PERMISSION_GRANTED) { 13069 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 13070 < Build.VERSION_CODES.FROYO) { 13071 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 13072 + Binder.getCallingUid()); 13073 return; 13074 } 13075 mContext.enforceCallingOrSelfPermission( 13076 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13077 } 13078 } 13079 13080 int user = UserHandle.getCallingUserId(); 13081 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 13082 scheduleWritePackageRestrictionsLocked(user); 13083 } 13084 } 13085 } 13086 13087 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 13088 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 13089 ArrayList<PreferredActivity> removed = null; 13090 boolean changed = false; 13091 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13092 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 13093 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13094 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 13095 continue; 13096 } 13097 Iterator<PreferredActivity> it = pir.filterIterator(); 13098 while (it.hasNext()) { 13099 PreferredActivity pa = it.next(); 13100 // Mark entry for removal only if it matches the package name 13101 // and the entry is of type "always". 13102 if (packageName == null || 13103 (pa.mPref.mComponent.getPackageName().equals(packageName) 13104 && pa.mPref.mAlways)) { 13105 if (removed == null) { 13106 removed = new ArrayList<PreferredActivity>(); 13107 } 13108 removed.add(pa); 13109 } 13110 } 13111 if (removed != null) { 13112 for (int j=0; j<removed.size(); j++) { 13113 PreferredActivity pa = removed.get(j); 13114 pir.removeFilter(pa); 13115 } 13116 changed = true; 13117 } 13118 } 13119 return changed; 13120 } 13121 13122 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 13123 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 13124 if (userId == UserHandle.USER_ALL) { 13125 if (mSettings.removeIntentFilterVerificationLPw(packageName, 13126 sUserManager.getUserIds())) { 13127 for (int oneUserId : sUserManager.getUserIds()) { 13128 scheduleWritePackageRestrictionsLocked(oneUserId); 13129 } 13130 } 13131 } else { 13132 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 13133 scheduleWritePackageRestrictionsLocked(userId); 13134 } 13135 } 13136 } 13137 13138 13139 void clearDefaultBrowserIfNeeded(String packageName) { 13140 for (int oneUserId : sUserManager.getUserIds()) { 13141 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 13142 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 13143 if (packageName.equals(defaultBrowserPackageName)) { 13144 setDefaultBrowserPackageName(null, oneUserId); 13145 } 13146 } 13147 } 13148 13149 @Override 13150 public void resetPreferredActivities(int userId) { 13151 /* TODO: Actually use userId. Why is it being passed in? */ 13152 mContext.enforceCallingOrSelfPermission( 13153 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13154 // writer 13155 synchronized (mPackages) { 13156 int user = UserHandle.getCallingUserId(); 13157 clearPackagePreferredActivitiesLPw(null, user); 13158 mSettings.readDefaultPreferredAppsLPw(this, user); 13159 scheduleWritePackageRestrictionsLocked(user); 13160 } 13161 } 13162 13163 @Override 13164 public int getPreferredActivities(List<IntentFilter> outFilters, 13165 List<ComponentName> outActivities, String packageName) { 13166 13167 int num = 0; 13168 final int userId = UserHandle.getCallingUserId(); 13169 // reader 13170 synchronized (mPackages) { 13171 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 13172 if (pir != null) { 13173 final Iterator<PreferredActivity> it = pir.filterIterator(); 13174 while (it.hasNext()) { 13175 final PreferredActivity pa = it.next(); 13176 if (packageName == null 13177 || (pa.mPref.mComponent.getPackageName().equals(packageName) 13178 && pa.mPref.mAlways)) { 13179 if (outFilters != null) { 13180 outFilters.add(new IntentFilter(pa)); 13181 } 13182 if (outActivities != null) { 13183 outActivities.add(pa.mPref.mComponent); 13184 } 13185 } 13186 } 13187 } 13188 } 13189 13190 return num; 13191 } 13192 13193 @Override 13194 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 13195 int userId) { 13196 int callingUid = Binder.getCallingUid(); 13197 if (callingUid != Process.SYSTEM_UID) { 13198 throw new SecurityException( 13199 "addPersistentPreferredActivity can only be run by the system"); 13200 } 13201 if (filter.countActions() == 0) { 13202 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 13203 return; 13204 } 13205 synchronized (mPackages) { 13206 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 13207 " :"); 13208 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 13209 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 13210 new PersistentPreferredActivity(filter, activity)); 13211 scheduleWritePackageRestrictionsLocked(userId); 13212 } 13213 } 13214 13215 @Override 13216 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 13217 int callingUid = Binder.getCallingUid(); 13218 if (callingUid != Process.SYSTEM_UID) { 13219 throw new SecurityException( 13220 "clearPackagePersistentPreferredActivities can only be run by the system"); 13221 } 13222 ArrayList<PersistentPreferredActivity> removed = null; 13223 boolean changed = false; 13224 synchronized (mPackages) { 13225 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 13226 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 13227 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 13228 .valueAt(i); 13229 if (userId != thisUserId) { 13230 continue; 13231 } 13232 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 13233 while (it.hasNext()) { 13234 PersistentPreferredActivity ppa = it.next(); 13235 // Mark entry for removal only if it matches the package name. 13236 if (ppa.mComponent.getPackageName().equals(packageName)) { 13237 if (removed == null) { 13238 removed = new ArrayList<PersistentPreferredActivity>(); 13239 } 13240 removed.add(ppa); 13241 } 13242 } 13243 if (removed != null) { 13244 for (int j=0; j<removed.size(); j++) { 13245 PersistentPreferredActivity ppa = removed.get(j); 13246 ppir.removeFilter(ppa); 13247 } 13248 changed = true; 13249 } 13250 } 13251 13252 if (changed) { 13253 scheduleWritePackageRestrictionsLocked(userId); 13254 } 13255 } 13256 } 13257 13258 /** 13259 * Non-Binder method, support for the backup/restore mechanism: write the 13260 * full set of preferred activities in its canonical XML format. Returns true 13261 * on success; false otherwise. 13262 */ 13263 @Override 13264 public byte[] getPreferredActivityBackup(int userId) { 13265 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 13266 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 13267 } 13268 13269 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 13270 try { 13271 final XmlSerializer serializer = new FastXmlSerializer(); 13272 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 13273 serializer.startDocument(null, true); 13274 serializer.startTag(null, TAG_PREFERRED_BACKUP); 13275 13276 synchronized (mPackages) { 13277 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 13278 } 13279 13280 serializer.endTag(null, TAG_PREFERRED_BACKUP); 13281 serializer.endDocument(); 13282 serializer.flush(); 13283 } catch (Exception e) { 13284 if (DEBUG_BACKUP) { 13285 Slog.e(TAG, "Unable to write preferred activities for backup", e); 13286 } 13287 return null; 13288 } 13289 13290 return dataStream.toByteArray(); 13291 } 13292 13293 @Override 13294 public void restorePreferredActivities(byte[] backup, int userId) { 13295 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 13296 throw new SecurityException("Only the system may call restorePreferredActivities()"); 13297 } 13298 13299 try { 13300 final XmlPullParser parser = Xml.newPullParser(); 13301 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 13302 13303 int type; 13304 while ((type = parser.next()) != XmlPullParser.START_TAG 13305 && type != XmlPullParser.END_DOCUMENT) { 13306 } 13307 if (type != XmlPullParser.START_TAG) { 13308 // oops didn't find a start tag?! 13309 if (DEBUG_BACKUP) { 13310 Slog.e(TAG, "Didn't find start tag during restore"); 13311 } 13312 return; 13313 } 13314 13315 // this is supposed to be TAG_PREFERRED_BACKUP 13316 if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) { 13317 if (DEBUG_BACKUP) { 13318 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 13319 } 13320 return; 13321 } 13322 13323 // skip interfering stuff, then we're aligned with the backing implementation 13324 while ((type = parser.next()) == XmlPullParser.TEXT) { } 13325 synchronized (mPackages) { 13326 mSettings.readPreferredActivitiesLPw(parser, userId); 13327 } 13328 } catch (Exception e) { 13329 if (DEBUG_BACKUP) { 13330 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 13331 } 13332 } 13333 } 13334 13335 @Override 13336 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 13337 int sourceUserId, int targetUserId, int flags) { 13338 mContext.enforceCallingOrSelfPermission( 13339 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 13340 int callingUid = Binder.getCallingUid(); 13341 enforceOwnerRights(ownerPackage, callingUid); 13342 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 13343 if (intentFilter.countActions() == 0) { 13344 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 13345 return; 13346 } 13347 synchronized (mPackages) { 13348 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 13349 ownerPackage, targetUserId, flags); 13350 CrossProfileIntentResolver resolver = 13351 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 13352 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 13353 // We have all those whose filter is equal. Now checking if the rest is equal as well. 13354 if (existing != null) { 13355 int size = existing.size(); 13356 for (int i = 0; i < size; i++) { 13357 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 13358 return; 13359 } 13360 } 13361 } 13362 resolver.addFilter(newFilter); 13363 scheduleWritePackageRestrictionsLocked(sourceUserId); 13364 } 13365 } 13366 13367 @Override 13368 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 13369 mContext.enforceCallingOrSelfPermission( 13370 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 13371 int callingUid = Binder.getCallingUid(); 13372 enforceOwnerRights(ownerPackage, callingUid); 13373 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 13374 synchronized (mPackages) { 13375 CrossProfileIntentResolver resolver = 13376 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 13377 ArraySet<CrossProfileIntentFilter> set = 13378 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 13379 for (CrossProfileIntentFilter filter : set) { 13380 if (filter.getOwnerPackage().equals(ownerPackage)) { 13381 resolver.removeFilter(filter); 13382 } 13383 } 13384 scheduleWritePackageRestrictionsLocked(sourceUserId); 13385 } 13386 } 13387 13388 // Enforcing that callingUid is owning pkg on userId 13389 private void enforceOwnerRights(String pkg, int callingUid) { 13390 // The system owns everything. 13391 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 13392 return; 13393 } 13394 int callingUserId = UserHandle.getUserId(callingUid); 13395 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 13396 if (pi == null) { 13397 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 13398 + callingUserId); 13399 } 13400 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 13401 throw new SecurityException("Calling uid " + callingUid 13402 + " does not own package " + pkg); 13403 } 13404 } 13405 13406 @Override 13407 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 13408 Intent intent = new Intent(Intent.ACTION_MAIN); 13409 intent.addCategory(Intent.CATEGORY_HOME); 13410 13411 final int callingUserId = UserHandle.getCallingUserId(); 13412 List<ResolveInfo> list = queryIntentActivities(intent, null, 13413 PackageManager.GET_META_DATA, callingUserId); 13414 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 13415 true, false, false, callingUserId); 13416 13417 allHomeCandidates.clear(); 13418 if (list != null) { 13419 for (ResolveInfo ri : list) { 13420 allHomeCandidates.add(ri); 13421 } 13422 } 13423 return (preferred == null || preferred.activityInfo == null) 13424 ? null 13425 : new ComponentName(preferred.activityInfo.packageName, 13426 preferred.activityInfo.name); 13427 } 13428 13429 @Override 13430 public void setApplicationEnabledSetting(String appPackageName, 13431 int newState, int flags, int userId, String callingPackage) { 13432 if (!sUserManager.exists(userId)) return; 13433 if (callingPackage == null) { 13434 callingPackage = Integer.toString(Binder.getCallingUid()); 13435 } 13436 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 13437 } 13438 13439 @Override 13440 public void setComponentEnabledSetting(ComponentName componentName, 13441 int newState, int flags, int userId) { 13442 if (!sUserManager.exists(userId)) return; 13443 setEnabledSetting(componentName.getPackageName(), 13444 componentName.getClassName(), newState, flags, userId, null); 13445 } 13446 13447 private void setEnabledSetting(final String packageName, String className, int newState, 13448 final int flags, int userId, String callingPackage) { 13449 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 13450 || newState == COMPONENT_ENABLED_STATE_ENABLED 13451 || newState == COMPONENT_ENABLED_STATE_DISABLED 13452 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 13453 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 13454 throw new IllegalArgumentException("Invalid new component state: " 13455 + newState); 13456 } 13457 PackageSetting pkgSetting; 13458 final int uid = Binder.getCallingUid(); 13459 final int permission = mContext.checkCallingOrSelfPermission( 13460 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 13461 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 13462 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 13463 boolean sendNow = false; 13464 boolean isApp = (className == null); 13465 String componentName = isApp ? packageName : className; 13466 int packageUid = -1; 13467 ArrayList<String> components; 13468 13469 // writer 13470 synchronized (mPackages) { 13471 pkgSetting = mSettings.mPackages.get(packageName); 13472 if (pkgSetting == null) { 13473 if (className == null) { 13474 throw new IllegalArgumentException( 13475 "Unknown package: " + packageName); 13476 } 13477 throw new IllegalArgumentException( 13478 "Unknown component: " + packageName 13479 + "/" + className); 13480 } 13481 // Allow root and verify that userId is not being specified by a different user 13482 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 13483 throw new SecurityException( 13484 "Permission Denial: attempt to change component state from pid=" 13485 + Binder.getCallingPid() 13486 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 13487 } 13488 if (className == null) { 13489 // We're dealing with an application/package level state change 13490 if (pkgSetting.getEnabled(userId) == newState) { 13491 // Nothing to do 13492 return; 13493 } 13494 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 13495 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 13496 // Don't care about who enables an app. 13497 callingPackage = null; 13498 } 13499 pkgSetting.setEnabled(newState, userId, callingPackage); 13500 // pkgSetting.pkg.mSetEnabled = newState; 13501 } else { 13502 // We're dealing with a component level state change 13503 // First, verify that this is a valid class name. 13504 PackageParser.Package pkg = pkgSetting.pkg; 13505 if (pkg == null || !pkg.hasComponentClassName(className)) { 13506 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 13507 throw new IllegalArgumentException("Component class " + className 13508 + " does not exist in " + packageName); 13509 } else { 13510 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 13511 + className + " does not exist in " + packageName); 13512 } 13513 } 13514 switch (newState) { 13515 case COMPONENT_ENABLED_STATE_ENABLED: 13516 if (!pkgSetting.enableComponentLPw(className, userId)) { 13517 return; 13518 } 13519 break; 13520 case COMPONENT_ENABLED_STATE_DISABLED: 13521 if (!pkgSetting.disableComponentLPw(className, userId)) { 13522 return; 13523 } 13524 break; 13525 case COMPONENT_ENABLED_STATE_DEFAULT: 13526 if (!pkgSetting.restoreComponentLPw(className, userId)) { 13527 return; 13528 } 13529 break; 13530 default: 13531 Slog.e(TAG, "Invalid new component state: " + newState); 13532 return; 13533 } 13534 } 13535 scheduleWritePackageRestrictionsLocked(userId); 13536 components = mPendingBroadcasts.get(userId, packageName); 13537 final boolean newPackage = components == null; 13538 if (newPackage) { 13539 components = new ArrayList<String>(); 13540 } 13541 if (!components.contains(componentName)) { 13542 components.add(componentName); 13543 } 13544 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 13545 sendNow = true; 13546 // Purge entry from pending broadcast list if another one exists already 13547 // since we are sending one right away. 13548 mPendingBroadcasts.remove(userId, packageName); 13549 } else { 13550 if (newPackage) { 13551 mPendingBroadcasts.put(userId, packageName, components); 13552 } 13553 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 13554 // Schedule a message 13555 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 13556 } 13557 } 13558 } 13559 13560 long callingId = Binder.clearCallingIdentity(); 13561 try { 13562 if (sendNow) { 13563 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 13564 sendPackageChangedBroadcast(packageName, 13565 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 13566 } 13567 } finally { 13568 Binder.restoreCallingIdentity(callingId); 13569 } 13570 } 13571 13572 private void sendPackageChangedBroadcast(String packageName, 13573 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 13574 if (DEBUG_INSTALL) 13575 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 13576 + componentNames); 13577 Bundle extras = new Bundle(4); 13578 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 13579 String nameList[] = new String[componentNames.size()]; 13580 componentNames.toArray(nameList); 13581 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 13582 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 13583 extras.putInt(Intent.EXTRA_UID, packageUid); 13584 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 13585 new int[] {UserHandle.getUserId(packageUid)}); 13586 } 13587 13588 @Override 13589 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 13590 if (!sUserManager.exists(userId)) return; 13591 final int uid = Binder.getCallingUid(); 13592 final int permission = mContext.checkCallingOrSelfPermission( 13593 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 13594 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 13595 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 13596 // writer 13597 synchronized (mPackages) { 13598 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 13599 allowedByPermission, uid, userId)) { 13600 scheduleWritePackageRestrictionsLocked(userId); 13601 } 13602 } 13603 } 13604 13605 @Override 13606 public String getInstallerPackageName(String packageName) { 13607 // reader 13608 synchronized (mPackages) { 13609 return mSettings.getInstallerPackageNameLPr(packageName); 13610 } 13611 } 13612 13613 @Override 13614 public int getApplicationEnabledSetting(String packageName, int userId) { 13615 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13616 int uid = Binder.getCallingUid(); 13617 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 13618 // reader 13619 synchronized (mPackages) { 13620 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 13621 } 13622 } 13623 13624 @Override 13625 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 13626 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 13627 int uid = Binder.getCallingUid(); 13628 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 13629 // reader 13630 synchronized (mPackages) { 13631 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 13632 } 13633 } 13634 13635 @Override 13636 public void enterSafeMode() { 13637 enforceSystemOrRoot("Only the system can request entering safe mode"); 13638 13639 if (!mSystemReady) { 13640 mSafeMode = true; 13641 } 13642 } 13643 13644 @Override 13645 public void systemReady() { 13646 mSystemReady = true; 13647 13648 // Read the compatibilty setting when the system is ready. 13649 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 13650 mContext.getContentResolver(), 13651 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 13652 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 13653 if (DEBUG_SETTINGS) { 13654 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 13655 } 13656 13657 synchronized (mPackages) { 13658 // Verify that all of the preferred activity components actually 13659 // exist. It is possible for applications to be updated and at 13660 // that point remove a previously declared activity component that 13661 // had been set as a preferred activity. We try to clean this up 13662 // the next time we encounter that preferred activity, but it is 13663 // possible for the user flow to never be able to return to that 13664 // situation so here we do a sanity check to make sure we haven't 13665 // left any junk around. 13666 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 13667 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 13668 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 13669 removed.clear(); 13670 for (PreferredActivity pa : pir.filterSet()) { 13671 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 13672 removed.add(pa); 13673 } 13674 } 13675 if (removed.size() > 0) { 13676 for (int r=0; r<removed.size(); r++) { 13677 PreferredActivity pa = removed.get(r); 13678 Slog.w(TAG, "Removing dangling preferred activity: " 13679 + pa.mPref.mComponent); 13680 pir.removeFilter(pa); 13681 } 13682 mSettings.writePackageRestrictionsLPr( 13683 mSettings.mPreferredActivities.keyAt(i)); 13684 } 13685 } 13686 } 13687 sUserManager.systemReady(); 13688 13689 // Kick off any messages waiting for system ready 13690 if (mPostSystemReadyMessages != null) { 13691 for (Message msg : mPostSystemReadyMessages) { 13692 msg.sendToTarget(); 13693 } 13694 mPostSystemReadyMessages = null; 13695 } 13696 13697 // Watch for external volumes that come and go over time 13698 final StorageManager storage = mContext.getSystemService(StorageManager.class); 13699 storage.registerListener(mStorageListener); 13700 13701 mInstallerService.systemReady(); 13702 mPackageDexOptimizer.systemReady(); 13703 } 13704 13705 @Override 13706 public boolean isSafeMode() { 13707 return mSafeMode; 13708 } 13709 13710 @Override 13711 public boolean hasSystemUidErrors() { 13712 return mHasSystemUidErrors; 13713 } 13714 13715 static String arrayToString(int[] array) { 13716 StringBuffer buf = new StringBuffer(128); 13717 buf.append('['); 13718 if (array != null) { 13719 for (int i=0; i<array.length; i++) { 13720 if (i > 0) buf.append(", "); 13721 buf.append(array[i]); 13722 } 13723 } 13724 buf.append(']'); 13725 return buf.toString(); 13726 } 13727 13728 static class DumpState { 13729 public static final int DUMP_LIBS = 1 << 0; 13730 public static final int DUMP_FEATURES = 1 << 1; 13731 public static final int DUMP_RESOLVERS = 1 << 2; 13732 public static final int DUMP_PERMISSIONS = 1 << 3; 13733 public static final int DUMP_PACKAGES = 1 << 4; 13734 public static final int DUMP_SHARED_USERS = 1 << 5; 13735 public static final int DUMP_MESSAGES = 1 << 6; 13736 public static final int DUMP_PROVIDERS = 1 << 7; 13737 public static final int DUMP_VERIFIERS = 1 << 8; 13738 public static final int DUMP_PREFERRED = 1 << 9; 13739 public static final int DUMP_PREFERRED_XML = 1 << 10; 13740 public static final int DUMP_KEYSETS = 1 << 11; 13741 public static final int DUMP_VERSION = 1 << 12; 13742 public static final int DUMP_INSTALLS = 1 << 13; 13743 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14; 13744 public static final int DUMP_DOMAIN_PREFERRED = 1 << 15; 13745 13746 public static final int OPTION_SHOW_FILTERS = 1 << 0; 13747 13748 private int mTypes; 13749 13750 private int mOptions; 13751 13752 private boolean mTitlePrinted; 13753 13754 private SharedUserSetting mSharedUser; 13755 13756 public boolean isDumping(int type) { 13757 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 13758 return true; 13759 } 13760 13761 return (mTypes & type) != 0; 13762 } 13763 13764 public void setDump(int type) { 13765 mTypes |= type; 13766 } 13767 13768 public boolean isOptionEnabled(int option) { 13769 return (mOptions & option) != 0; 13770 } 13771 13772 public void setOptionEnabled(int option) { 13773 mOptions |= option; 13774 } 13775 13776 public boolean onTitlePrinted() { 13777 final boolean printed = mTitlePrinted; 13778 mTitlePrinted = true; 13779 return printed; 13780 } 13781 13782 public boolean getTitlePrinted() { 13783 return mTitlePrinted; 13784 } 13785 13786 public void setTitlePrinted(boolean enabled) { 13787 mTitlePrinted = enabled; 13788 } 13789 13790 public SharedUserSetting getSharedUser() { 13791 return mSharedUser; 13792 } 13793 13794 public void setSharedUser(SharedUserSetting user) { 13795 mSharedUser = user; 13796 } 13797 } 13798 13799 @Override 13800 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 13801 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 13802 != PackageManager.PERMISSION_GRANTED) { 13803 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 13804 + Binder.getCallingPid() 13805 + ", uid=" + Binder.getCallingUid() 13806 + " without permission " 13807 + android.Manifest.permission.DUMP); 13808 return; 13809 } 13810 13811 DumpState dumpState = new DumpState(); 13812 boolean fullPreferred = false; 13813 boolean checkin = false; 13814 13815 String packageName = null; 13816 13817 int opti = 0; 13818 while (opti < args.length) { 13819 String opt = args[opti]; 13820 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13821 break; 13822 } 13823 opti++; 13824 13825 if ("-a".equals(opt)) { 13826 // Right now we only know how to print all. 13827 } else if ("-h".equals(opt)) { 13828 pw.println("Package manager dump options:"); 13829 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 13830 pw.println(" --checkin: dump for a checkin"); 13831 pw.println(" -f: print details of intent filters"); 13832 pw.println(" -h: print this help"); 13833 pw.println(" cmd may be one of:"); 13834 pw.println(" l[ibraries]: list known shared libraries"); 13835 pw.println(" f[ibraries]: list device features"); 13836 pw.println(" k[eysets]: print known keysets"); 13837 pw.println(" r[esolvers]: dump intent resolvers"); 13838 pw.println(" perm[issions]: dump permissions"); 13839 pw.println(" pref[erred]: print preferred package settings"); 13840 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 13841 pw.println(" prov[iders]: dump content providers"); 13842 pw.println(" p[ackages]: dump installed packages"); 13843 pw.println(" s[hared-users]: dump shared user IDs"); 13844 pw.println(" m[essages]: print collected runtime messages"); 13845 pw.println(" v[erifiers]: print package verifier info"); 13846 pw.println(" version: print database version info"); 13847 pw.println(" write: write current settings now"); 13848 pw.println(" <package.name>: info about given package"); 13849 pw.println(" installs: details about install sessions"); 13850 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 13851 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 13852 return; 13853 } else if ("--checkin".equals(opt)) { 13854 checkin = true; 13855 } else if ("-f".equals(opt)) { 13856 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13857 } else { 13858 pw.println("Unknown argument: " + opt + "; use -h for help"); 13859 } 13860 } 13861 13862 // Is the caller requesting to dump a particular piece of data? 13863 if (opti < args.length) { 13864 String cmd = args[opti]; 13865 opti++; 13866 // Is this a package name? 13867 if ("android".equals(cmd) || cmd.contains(".")) { 13868 packageName = cmd; 13869 // When dumping a single package, we always dump all of its 13870 // filter information since the amount of data will be reasonable. 13871 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 13872 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 13873 dumpState.setDump(DumpState.DUMP_LIBS); 13874 } else if ("f".equals(cmd) || "features".equals(cmd)) { 13875 dumpState.setDump(DumpState.DUMP_FEATURES); 13876 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 13877 dumpState.setDump(DumpState.DUMP_RESOLVERS); 13878 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 13879 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 13880 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 13881 dumpState.setDump(DumpState.DUMP_PREFERRED); 13882 } else if ("preferred-xml".equals(cmd)) { 13883 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 13884 if (opti < args.length && "--full".equals(args[opti])) { 13885 fullPreferred = true; 13886 opti++; 13887 } 13888 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 13889 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 13890 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 13891 dumpState.setDump(DumpState.DUMP_PACKAGES); 13892 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 13893 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 13894 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 13895 dumpState.setDump(DumpState.DUMP_PROVIDERS); 13896 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 13897 dumpState.setDump(DumpState.DUMP_MESSAGES); 13898 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 13899 dumpState.setDump(DumpState.DUMP_VERIFIERS); 13900 } else if ("i".equals(cmd) || "ifv".equals(cmd) 13901 || "intent-filter-verifiers".equals(cmd)) { 13902 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 13903 } else if ("version".equals(cmd)) { 13904 dumpState.setDump(DumpState.DUMP_VERSION); 13905 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 13906 dumpState.setDump(DumpState.DUMP_KEYSETS); 13907 } else if ("installs".equals(cmd)) { 13908 dumpState.setDump(DumpState.DUMP_INSTALLS); 13909 } else if ("write".equals(cmd)) { 13910 synchronized (mPackages) { 13911 mSettings.writeLPr(); 13912 pw.println("Settings written."); 13913 return; 13914 } 13915 } 13916 } 13917 13918 if (checkin) { 13919 pw.println("vers,1"); 13920 } 13921 13922 // reader 13923 synchronized (mPackages) { 13924 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 13925 if (!checkin) { 13926 if (dumpState.onTitlePrinted()) 13927 pw.println(); 13928 pw.println("Database versions:"); 13929 pw.print(" SDK Version:"); 13930 pw.print(" internal="); 13931 pw.print(mSettings.mInternalSdkPlatform); 13932 pw.print(" external="); 13933 pw.println(mSettings.mExternalSdkPlatform); 13934 pw.print(" DB Version:"); 13935 pw.print(" internal="); 13936 pw.print(mSettings.mInternalDatabaseVersion); 13937 pw.print(" external="); 13938 pw.println(mSettings.mExternalDatabaseVersion); 13939 } 13940 } 13941 13942 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 13943 if (!checkin) { 13944 if (dumpState.onTitlePrinted()) 13945 pw.println(); 13946 pw.println("Verifiers:"); 13947 pw.print(" Required: "); 13948 pw.print(mRequiredVerifierPackage); 13949 pw.print(" (uid="); 13950 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 13951 pw.println(")"); 13952 } else if (mRequiredVerifierPackage != null) { 13953 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 13954 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 13955 } 13956 } 13957 13958 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 13959 packageName == null) { 13960 if (mIntentFilterVerifierComponent != null) { 13961 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 13962 if (!checkin) { 13963 if (dumpState.onTitlePrinted()) 13964 pw.println(); 13965 pw.println("Intent Filter Verifier:"); 13966 pw.print(" Using: "); 13967 pw.print(verifierPackageName); 13968 pw.print(" (uid="); 13969 pw.print(getPackageUid(verifierPackageName, 0)); 13970 pw.println(")"); 13971 } else if (verifierPackageName != null) { 13972 pw.print("ifv,"); pw.print(verifierPackageName); 13973 pw.print(","); pw.println(getPackageUid(verifierPackageName, 0)); 13974 } 13975 } else { 13976 pw.println(); 13977 pw.println("No Intent Filter Verifier available!"); 13978 } 13979 } 13980 13981 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 13982 boolean printedHeader = false; 13983 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 13984 while (it.hasNext()) { 13985 String name = it.next(); 13986 SharedLibraryEntry ent = mSharedLibraries.get(name); 13987 if (!checkin) { 13988 if (!printedHeader) { 13989 if (dumpState.onTitlePrinted()) 13990 pw.println(); 13991 pw.println("Libraries:"); 13992 printedHeader = true; 13993 } 13994 pw.print(" "); 13995 } else { 13996 pw.print("lib,"); 13997 } 13998 pw.print(name); 13999 if (!checkin) { 14000 pw.print(" -> "); 14001 } 14002 if (ent.path != null) { 14003 if (!checkin) { 14004 pw.print("(jar) "); 14005 pw.print(ent.path); 14006 } else { 14007 pw.print(",jar,"); 14008 pw.print(ent.path); 14009 } 14010 } else { 14011 if (!checkin) { 14012 pw.print("(apk) "); 14013 pw.print(ent.apk); 14014 } else { 14015 pw.print(",apk,"); 14016 pw.print(ent.apk); 14017 } 14018 } 14019 pw.println(); 14020 } 14021 } 14022 14023 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 14024 if (dumpState.onTitlePrinted()) 14025 pw.println(); 14026 if (!checkin) { 14027 pw.println("Features:"); 14028 } 14029 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 14030 while (it.hasNext()) { 14031 String name = it.next(); 14032 if (!checkin) { 14033 pw.print(" "); 14034 } else { 14035 pw.print("feat,"); 14036 } 14037 pw.println(name); 14038 } 14039 } 14040 14041 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 14042 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 14043 : "Activity Resolver Table:", " ", packageName, 14044 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 14045 dumpState.setTitlePrinted(true); 14046 } 14047 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 14048 : "Receiver Resolver Table:", " ", packageName, 14049 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 14050 dumpState.setTitlePrinted(true); 14051 } 14052 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 14053 : "Service Resolver Table:", " ", packageName, 14054 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 14055 dumpState.setTitlePrinted(true); 14056 } 14057 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 14058 : "Provider Resolver Table:", " ", packageName, 14059 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 14060 dumpState.setTitlePrinted(true); 14061 } 14062 } 14063 14064 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 14065 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 14066 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 14067 int user = mSettings.mPreferredActivities.keyAt(i); 14068 if (pir.dump(pw, 14069 dumpState.getTitlePrinted() 14070 ? "\nPreferred Activities User " + user + ":" 14071 : "Preferred Activities User " + user + ":", " ", 14072 packageName, true, false)) { 14073 dumpState.setTitlePrinted(true); 14074 } 14075 } 14076 } 14077 14078 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 14079 pw.flush(); 14080 FileOutputStream fout = new FileOutputStream(fd); 14081 BufferedOutputStream str = new BufferedOutputStream(fout); 14082 XmlSerializer serializer = new FastXmlSerializer(); 14083 try { 14084 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 14085 serializer.startDocument(null, true); 14086 serializer.setFeature( 14087 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 14088 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 14089 serializer.endDocument(); 14090 serializer.flush(); 14091 } catch (IllegalArgumentException e) { 14092 pw.println("Failed writing: " + e); 14093 } catch (IllegalStateException e) { 14094 pw.println("Failed writing: " + e); 14095 } catch (IOException e) { 14096 pw.println("Failed writing: " + e); 14097 } 14098 } 14099 14100 if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) { 14101 pw.println(); 14102 int count = mSettings.mPackages.size(); 14103 if (count == 0) { 14104 pw.println("No domain preferred apps!"); 14105 pw.println(); 14106 } else { 14107 final String prefix = " "; 14108 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 14109 if (allPackageSettings.size() == 0) { 14110 pw.println("No domain preferred apps!"); 14111 pw.println(); 14112 } else { 14113 pw.println("Domain preferred apps status:"); 14114 pw.println(); 14115 count = 0; 14116 for (PackageSetting ps : allPackageSettings) { 14117 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 14118 if (ivi == null || ivi.getPackageName() == null) continue; 14119 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 14120 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 14121 pw.println(prefix + "Status: " + ivi.getStatusString()); 14122 pw.println(); 14123 count++; 14124 } 14125 if (count == 0) { 14126 pw.println(prefix + "No domain preferred app status!"); 14127 pw.println(); 14128 } 14129 for (int userId : sUserManager.getUserIds()) { 14130 pw.println("Domain preferred apps for User " + userId + ":"); 14131 pw.println(); 14132 count = 0; 14133 for (PackageSetting ps : allPackageSettings) { 14134 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 14135 if (ivi == null || ivi.getPackageName() == null) { 14136 continue; 14137 } 14138 final int status = ps.getDomainVerificationStatusForUser(userId); 14139 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 14140 continue; 14141 } 14142 pw.println(prefix + "Package Name: " + ivi.getPackageName()); 14143 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 14144 String statusStr = IntentFilterVerificationInfo. 14145 getStatusStringFromValue(status); 14146 pw.println(prefix + "Status: " + statusStr); 14147 pw.println(); 14148 count++; 14149 } 14150 if (count == 0) { 14151 pw.println(prefix + "No domain preferred apps!"); 14152 pw.println(); 14153 } 14154 } 14155 } 14156 } 14157 } 14158 14159 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 14160 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 14161 if (packageName == null) { 14162 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 14163 if (iperm == 0) { 14164 if (dumpState.onTitlePrinted()) 14165 pw.println(); 14166 pw.println("AppOp Permissions:"); 14167 } 14168 pw.print(" AppOp Permission "); 14169 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 14170 pw.println(":"); 14171 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 14172 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 14173 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 14174 } 14175 } 14176 } 14177 } 14178 14179 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 14180 boolean printedSomething = false; 14181 for (PackageParser.Provider p : mProviders.mProviders.values()) { 14182 if (packageName != null && !packageName.equals(p.info.packageName)) { 14183 continue; 14184 } 14185 if (!printedSomething) { 14186 if (dumpState.onTitlePrinted()) 14187 pw.println(); 14188 pw.println("Registered ContentProviders:"); 14189 printedSomething = true; 14190 } 14191 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 14192 pw.print(" "); pw.println(p.toString()); 14193 } 14194 printedSomething = false; 14195 for (Map.Entry<String, PackageParser.Provider> entry : 14196 mProvidersByAuthority.entrySet()) { 14197 PackageParser.Provider p = entry.getValue(); 14198 if (packageName != null && !packageName.equals(p.info.packageName)) { 14199 continue; 14200 } 14201 if (!printedSomething) { 14202 if (dumpState.onTitlePrinted()) 14203 pw.println(); 14204 pw.println("ContentProvider Authorities:"); 14205 printedSomething = true; 14206 } 14207 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 14208 pw.print(" "); pw.println(p.toString()); 14209 if (p.info != null && p.info.applicationInfo != null) { 14210 final String appInfo = p.info.applicationInfo.toString(); 14211 pw.print(" applicationInfo="); pw.println(appInfo); 14212 } 14213 } 14214 } 14215 14216 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 14217 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 14218 } 14219 14220 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 14221 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 14222 } 14223 14224 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 14225 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin); 14226 } 14227 14228 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 14229 // XXX should handle packageName != null by dumping only install data that 14230 // the given package is involved with. 14231 if (dumpState.onTitlePrinted()) pw.println(); 14232 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 14233 } 14234 14235 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 14236 if (dumpState.onTitlePrinted()) pw.println(); 14237 mSettings.dumpReadMessagesLPr(pw, dumpState); 14238 14239 pw.println(); 14240 pw.println("Package warning messages:"); 14241 BufferedReader in = null; 14242 String line = null; 14243 try { 14244 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 14245 while ((line = in.readLine()) != null) { 14246 if (line.contains("ignored: updated version")) continue; 14247 pw.println(line); 14248 } 14249 } catch (IOException ignored) { 14250 } finally { 14251 IoUtils.closeQuietly(in); 14252 } 14253 } 14254 14255 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 14256 BufferedReader in = null; 14257 String line = null; 14258 try { 14259 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 14260 while ((line = in.readLine()) != null) { 14261 if (line.contains("ignored: updated version")) continue; 14262 pw.print("msg,"); 14263 pw.println(line); 14264 } 14265 } catch (IOException ignored) { 14266 } finally { 14267 IoUtils.closeQuietly(in); 14268 } 14269 } 14270 } 14271 } 14272 14273 // ------- apps on sdcard specific code ------- 14274 static final boolean DEBUG_SD_INSTALL = false; 14275 14276 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 14277 14278 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 14279 14280 private boolean mMediaMounted = false; 14281 14282 static String getEncryptKey() { 14283 try { 14284 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 14285 SD_ENCRYPTION_KEYSTORE_NAME); 14286 if (sdEncKey == null) { 14287 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 14288 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 14289 if (sdEncKey == null) { 14290 Slog.e(TAG, "Failed to create encryption keys"); 14291 return null; 14292 } 14293 } 14294 return sdEncKey; 14295 } catch (NoSuchAlgorithmException nsae) { 14296 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 14297 return null; 14298 } catch (IOException ioe) { 14299 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 14300 return null; 14301 } 14302 } 14303 14304 /* 14305 * Update media status on PackageManager. 14306 */ 14307 @Override 14308 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 14309 int callingUid = Binder.getCallingUid(); 14310 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14311 throw new SecurityException("Media status can only be updated by the system"); 14312 } 14313 // reader; this apparently protects mMediaMounted, but should probably 14314 // be a different lock in that case. 14315 synchronized (mPackages) { 14316 Log.i(TAG, "Updating external media status from " 14317 + (mMediaMounted ? "mounted" : "unmounted") + " to " 14318 + (mediaStatus ? "mounted" : "unmounted")); 14319 if (DEBUG_SD_INSTALL) 14320 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 14321 + ", mMediaMounted=" + mMediaMounted); 14322 if (mediaStatus == mMediaMounted) { 14323 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 14324 : 0, -1); 14325 mHandler.sendMessage(msg); 14326 return; 14327 } 14328 mMediaMounted = mediaStatus; 14329 } 14330 // Queue up an async operation since the package installation may take a 14331 // little while. 14332 mHandler.post(new Runnable() { 14333 public void run() { 14334 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 14335 } 14336 }); 14337 } 14338 14339 /** 14340 * Called by MountService when the initial ASECs to scan are available. 14341 * Should block until all the ASEC containers are finished being scanned. 14342 */ 14343 public void scanAvailableAsecs() { 14344 updateExternalMediaStatusInner(true, false, false); 14345 if (mShouldRestoreconData) { 14346 SELinuxMMAC.setRestoreconDone(); 14347 mShouldRestoreconData = false; 14348 } 14349 } 14350 14351 /* 14352 * Collect information of applications on external media, map them against 14353 * existing containers and update information based on current mount status. 14354 * Please note that we always have to report status if reportStatus has been 14355 * set to true especially when unloading packages. 14356 */ 14357 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 14358 boolean externalStorage) { 14359 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 14360 int[] uidArr = EmptyArray.INT; 14361 14362 final String[] list = PackageHelper.getSecureContainerList(); 14363 if (ArrayUtils.isEmpty(list)) { 14364 Log.i(TAG, "No secure containers found"); 14365 } else { 14366 // Process list of secure containers and categorize them 14367 // as active or stale based on their package internal state. 14368 14369 // reader 14370 synchronized (mPackages) { 14371 for (String cid : list) { 14372 // Leave stages untouched for now; installer service owns them 14373 if (PackageInstallerService.isStageName(cid)) continue; 14374 14375 if (DEBUG_SD_INSTALL) 14376 Log.i(TAG, "Processing container " + cid); 14377 String pkgName = getAsecPackageName(cid); 14378 if (pkgName == null) { 14379 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 14380 continue; 14381 } 14382 if (DEBUG_SD_INSTALL) 14383 Log.i(TAG, "Looking for pkg : " + pkgName); 14384 14385 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14386 if (ps == null) { 14387 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 14388 continue; 14389 } 14390 14391 /* 14392 * Skip packages that are not external if we're unmounting 14393 * external storage. 14394 */ 14395 if (externalStorage && !isMounted && !isExternal(ps)) { 14396 continue; 14397 } 14398 14399 final AsecInstallArgs args = new AsecInstallArgs(cid, 14400 getAppDexInstructionSets(ps), ps.isForwardLocked()); 14401 // The package status is changed only if the code path 14402 // matches between settings and the container id. 14403 if (ps.codePathString != null 14404 && ps.codePathString.startsWith(args.getCodePath())) { 14405 if (DEBUG_SD_INSTALL) { 14406 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 14407 + " at code path: " + ps.codePathString); 14408 } 14409 14410 // We do have a valid package installed on sdcard 14411 processCids.put(args, ps.codePathString); 14412 final int uid = ps.appId; 14413 if (uid != -1) { 14414 uidArr = ArrayUtils.appendInt(uidArr, uid); 14415 } 14416 } else { 14417 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 14418 + ps.codePathString); 14419 } 14420 } 14421 } 14422 14423 Arrays.sort(uidArr); 14424 } 14425 14426 // Process packages with valid entries. 14427 if (isMounted) { 14428 if (DEBUG_SD_INSTALL) 14429 Log.i(TAG, "Loading packages"); 14430 loadMediaPackages(processCids, uidArr); 14431 startCleaningPackages(); 14432 mInstallerService.onSecureContainersAvailable(); 14433 } else { 14434 if (DEBUG_SD_INSTALL) 14435 Log.i(TAG, "Unloading packages"); 14436 unloadMediaPackages(processCids, uidArr, reportStatus); 14437 } 14438 } 14439 14440 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 14441 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 14442 final int size = infos.size(); 14443 final String[] packageNames = new String[size]; 14444 final int[] packageUids = new int[size]; 14445 for (int i = 0; i < size; i++) { 14446 final ApplicationInfo info = infos.get(i); 14447 packageNames[i] = info.packageName; 14448 packageUids[i] = info.uid; 14449 } 14450 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 14451 finishedReceiver); 14452 } 14453 14454 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 14455 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 14456 sendResourcesChangedBroadcast(mediaStatus, replacing, 14457 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 14458 } 14459 14460 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 14461 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 14462 int size = pkgList.length; 14463 if (size > 0) { 14464 // Send broadcasts here 14465 Bundle extras = new Bundle(); 14466 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 14467 if (uidArr != null) { 14468 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 14469 } 14470 if (replacing) { 14471 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 14472 } 14473 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 14474 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 14475 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 14476 } 14477 } 14478 14479 /* 14480 * Look at potentially valid container ids from processCids If package 14481 * information doesn't match the one on record or package scanning fails, 14482 * the cid is added to list of removeCids. We currently don't delete stale 14483 * containers. 14484 */ 14485 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) { 14486 ArrayList<String> pkgList = new ArrayList<String>(); 14487 Set<AsecInstallArgs> keys = processCids.keySet(); 14488 14489 for (AsecInstallArgs args : keys) { 14490 String codePath = processCids.get(args); 14491 if (DEBUG_SD_INSTALL) 14492 Log.i(TAG, "Loading container : " + args.cid); 14493 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14494 try { 14495 // Make sure there are no container errors first. 14496 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 14497 Slog.e(TAG, "Failed to mount cid : " + args.cid 14498 + " when installing from sdcard"); 14499 continue; 14500 } 14501 // Check code path here. 14502 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 14503 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 14504 + " does not match one in settings " + codePath); 14505 continue; 14506 } 14507 // Parse package 14508 int parseFlags = mDefParseFlags; 14509 if (args.isExternalAsec()) { 14510 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 14511 } 14512 if (args.isFwdLocked()) { 14513 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 14514 } 14515 14516 synchronized (mInstallLock) { 14517 PackageParser.Package pkg = null; 14518 try { 14519 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null); 14520 } catch (PackageManagerException e) { 14521 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 14522 } 14523 // Scan the package 14524 if (pkg != null) { 14525 /* 14526 * TODO why is the lock being held? doPostInstall is 14527 * called in other places without the lock. This needs 14528 * to be straightened out. 14529 */ 14530 // writer 14531 synchronized (mPackages) { 14532 retCode = PackageManager.INSTALL_SUCCEEDED; 14533 pkgList.add(pkg.packageName); 14534 // Post process args 14535 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 14536 pkg.applicationInfo.uid); 14537 } 14538 } else { 14539 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 14540 } 14541 } 14542 14543 } finally { 14544 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 14545 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 14546 } 14547 } 14548 } 14549 // writer 14550 synchronized (mPackages) { 14551 // If the platform SDK has changed since the last time we booted, 14552 // we need to re-grant app permission to catch any new ones that 14553 // appear. This is really a hack, and means that apps can in some 14554 // cases get permissions that the user didn't initially explicitly 14555 // allow... it would be nice to have some better way to handle 14556 // this situation. 14557 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 14558 if (regrantPermissions) 14559 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 14560 + mSdkVersion + "; regranting permissions for external storage"); 14561 mSettings.mExternalSdkPlatform = mSdkVersion; 14562 14563 // Make sure group IDs have been assigned, and any permission 14564 // changes in other apps are accounted for 14565 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 14566 | (regrantPermissions 14567 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 14568 : 0)); 14569 14570 mSettings.updateExternalDatabaseVersion(); 14571 14572 // can downgrade to reader 14573 // Persist settings 14574 mSettings.writeLPr(); 14575 } 14576 // Send a broadcast to let everyone know we are done processing 14577 if (pkgList.size() > 0) { 14578 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 14579 } 14580 } 14581 14582 /* 14583 * Utility method to unload a list of specified containers 14584 */ 14585 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 14586 // Just unmount all valid containers. 14587 for (AsecInstallArgs arg : cidArgs) { 14588 synchronized (mInstallLock) { 14589 arg.doPostDeleteLI(false); 14590 } 14591 } 14592 } 14593 14594 /* 14595 * Unload packages mounted on external media. This involves deleting package 14596 * data from internal structures, sending broadcasts about diabled packages, 14597 * gc'ing to free up references, unmounting all secure containers 14598 * corresponding to packages on external media, and posting a 14599 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 14600 * that we always have to post this message if status has been requested no 14601 * matter what. 14602 */ 14603 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 14604 final boolean reportStatus) { 14605 if (DEBUG_SD_INSTALL) 14606 Log.i(TAG, "unloading media packages"); 14607 ArrayList<String> pkgList = new ArrayList<String>(); 14608 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 14609 final Set<AsecInstallArgs> keys = processCids.keySet(); 14610 for (AsecInstallArgs args : keys) { 14611 String pkgName = args.getPackageName(); 14612 if (DEBUG_SD_INSTALL) 14613 Log.i(TAG, "Trying to unload pkg : " + pkgName); 14614 // Delete package internally 14615 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14616 synchronized (mInstallLock) { 14617 boolean res = deletePackageLI(pkgName, null, false, null, null, 14618 PackageManager.DELETE_KEEP_DATA, outInfo, false); 14619 if (res) { 14620 pkgList.add(pkgName); 14621 } else { 14622 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 14623 failedList.add(args); 14624 } 14625 } 14626 } 14627 14628 // reader 14629 synchronized (mPackages) { 14630 // We didn't update the settings after removing each package; 14631 // write them now for all packages. 14632 mSettings.writeLPr(); 14633 } 14634 14635 // We have to absolutely send UPDATED_MEDIA_STATUS only 14636 // after confirming that all the receivers processed the ordered 14637 // broadcast when packages get disabled, force a gc to clean things up. 14638 // and unload all the containers. 14639 if (pkgList.size() > 0) { 14640 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 14641 new IIntentReceiver.Stub() { 14642 public void performReceive(Intent intent, int resultCode, String data, 14643 Bundle extras, boolean ordered, boolean sticky, 14644 int sendingUser) throws RemoteException { 14645 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 14646 reportStatus ? 1 : 0, 1, keys); 14647 mHandler.sendMessage(msg); 14648 } 14649 }); 14650 } else { 14651 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 14652 keys); 14653 mHandler.sendMessage(msg); 14654 } 14655 } 14656 14657 private void loadPrivatePackages(VolumeInfo vol) { 14658 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 14659 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 14660 synchronized (mInstallLock) { 14661 synchronized (mPackages) { 14662 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14663 for (PackageSetting ps : packages) { 14664 final PackageParser.Package pkg; 14665 try { 14666 pkg = scanPackageLI(ps.codePath, parseFlags, 0, 0, null); 14667 loaded.add(pkg.applicationInfo); 14668 } catch (PackageManagerException e) { 14669 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 14670 } 14671 } 14672 14673 // TODO: regrant any permissions that changed based since original install 14674 14675 mSettings.writeLPr(); 14676 } 14677 } 14678 14679 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 14680 sendResourcesChangedBroadcast(true, false, loaded, null); 14681 } 14682 14683 private void unloadPrivatePackages(VolumeInfo vol) { 14684 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 14685 synchronized (mInstallLock) { 14686 synchronized (mPackages) { 14687 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); 14688 for (PackageSetting ps : packages) { 14689 if (ps.pkg == null) continue; 14690 14691 final ApplicationInfo info = ps.pkg.applicationInfo; 14692 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 14693 if (deletePackageLI(ps.name, null, false, null, null, 14694 PackageManager.DELETE_KEEP_DATA, outInfo, false)) { 14695 unloaded.add(info); 14696 } else { 14697 Slog.w(TAG, "Failed to unload " + ps.codePath); 14698 } 14699 } 14700 14701 mSettings.writeLPr(); 14702 } 14703 } 14704 14705 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 14706 sendResourcesChangedBroadcast(false, false, unloaded, null); 14707 } 14708 14709 private void unfreezePackage(String packageName) { 14710 synchronized (mPackages) { 14711 final PackageSetting ps = mSettings.mPackages.get(packageName); 14712 if (ps != null) { 14713 ps.frozen = false; 14714 } 14715 } 14716 } 14717 14718 @Override 14719 public int movePackage(final String packageName, final String volumeUuid) { 14720 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14721 14722 final int moveId = mNextMoveId.getAndIncrement(); 14723 try { 14724 movePackageInternal(packageName, volumeUuid, moveId); 14725 } catch (PackageManagerException e) { 14726 Slog.w(TAG, "Failed to move " + packageName, e); 14727 mMoveCallbacks.notifyStatusChanged(moveId, 14728 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 14729 } 14730 return moveId; 14731 } 14732 14733 private void movePackageInternal(final String packageName, final String volumeUuid, 14734 final int moveId) throws PackageManagerException { 14735 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 14736 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14737 final PackageManager pm = mContext.getPackageManager(); 14738 14739 final boolean currentAsec; 14740 final String currentVolumeUuid; 14741 final File codeFile; 14742 final String installerPackageName; 14743 final String packageAbiOverride; 14744 final int appId; 14745 final String seinfo; 14746 final String label; 14747 14748 // reader 14749 synchronized (mPackages) { 14750 final PackageParser.Package pkg = mPackages.get(packageName); 14751 final PackageSetting ps = mSettings.mPackages.get(packageName); 14752 if (pkg == null || ps == null) { 14753 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 14754 } 14755 14756 if (pkg.applicationInfo.isSystemApp()) { 14757 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 14758 "Cannot move system application"); 14759 } 14760 14761 if (Objects.equals(ps.volumeUuid, volumeUuid)) { 14762 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14763 "Package already moved to " + volumeUuid); 14764 } 14765 14766 final File probe = new File(pkg.codePath); 14767 final File probeOat = new File(probe, "oat"); 14768 if (!probe.isDirectory() || !probeOat.isDirectory()) { 14769 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14770 "Move only supported for modern cluster style installs"); 14771 } 14772 14773 if (ps.frozen) { 14774 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 14775 "Failed to move already frozen package"); 14776 } 14777 ps.frozen = true; 14778 14779 currentAsec = pkg.applicationInfo.isForwardLocked() 14780 || pkg.applicationInfo.isExternalAsec(); 14781 currentVolumeUuid = ps.volumeUuid; 14782 codeFile = new File(pkg.codePath); 14783 installerPackageName = ps.installerPackageName; 14784 packageAbiOverride = ps.cpuAbiOverrideString; 14785 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 14786 seinfo = pkg.applicationInfo.seinfo; 14787 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 14788 } 14789 14790 // Now that we're guarded by frozen state, kill app during move 14791 killApplication(packageName, appId, "move pkg"); 14792 14793 final Bundle extras = new Bundle(); 14794 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 14795 extras.putString(Intent.EXTRA_TITLE, label); 14796 mMoveCallbacks.notifyCreated(moveId, extras); 14797 14798 int installFlags; 14799 final boolean moveCompleteApp; 14800 final File measurePath; 14801 14802 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 14803 installFlags = INSTALL_INTERNAL; 14804 moveCompleteApp = !currentAsec; 14805 measurePath = Environment.getDataAppDirectory(volumeUuid); 14806 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 14807 installFlags = INSTALL_EXTERNAL; 14808 moveCompleteApp = false; 14809 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 14810 } else { 14811 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 14812 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 14813 || !volume.isMountedWritable()) { 14814 unfreezePackage(packageName); 14815 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14816 "Move location not mounted private volume"); 14817 } 14818 14819 Preconditions.checkState(!currentAsec); 14820 14821 installFlags = INSTALL_INTERNAL; 14822 moveCompleteApp = true; 14823 measurePath = Environment.getDataAppDirectory(volumeUuid); 14824 } 14825 14826 final PackageStats stats = new PackageStats(null, -1); 14827 synchronized (mInstaller) { 14828 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 14829 unfreezePackage(packageName); 14830 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14831 "Failed to measure package size"); 14832 } 14833 } 14834 14835 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 14836 + stats.dataSize); 14837 14838 final long startFreeBytes = measurePath.getFreeSpace(); 14839 final long sizeBytes; 14840 if (moveCompleteApp) { 14841 sizeBytes = stats.codeSize + stats.dataSize; 14842 } else { 14843 sizeBytes = stats.codeSize; 14844 } 14845 14846 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 14847 unfreezePackage(packageName); 14848 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 14849 "Not enough free space to move"); 14850 } 14851 14852 mMoveCallbacks.notifyStatusChanged(moveId, 10); 14853 14854 final CountDownLatch installedLatch = new CountDownLatch(1); 14855 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 14856 @Override 14857 public void onUserActionRequired(Intent intent) throws RemoteException { 14858 throw new IllegalStateException(); 14859 } 14860 14861 @Override 14862 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 14863 Bundle extras) throws RemoteException { 14864 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 14865 + PackageManager.installStatusToString(returnCode, msg)); 14866 14867 installedLatch.countDown(); 14868 14869 // Regardless of success or failure of the move operation, 14870 // always unfreeze the package 14871 unfreezePackage(packageName); 14872 14873 final int status = PackageManager.installStatusToPublicStatus(returnCode); 14874 switch (status) { 14875 case PackageInstaller.STATUS_SUCCESS: 14876 mMoveCallbacks.notifyStatusChanged(moveId, 14877 PackageManager.MOVE_SUCCEEDED); 14878 break; 14879 case PackageInstaller.STATUS_FAILURE_STORAGE: 14880 mMoveCallbacks.notifyStatusChanged(moveId, 14881 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 14882 break; 14883 default: 14884 mMoveCallbacks.notifyStatusChanged(moveId, 14885 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 14886 break; 14887 } 14888 } 14889 }; 14890 14891 final MoveInfo move; 14892 if (moveCompleteApp) { 14893 // Kick off a thread to report progress estimates 14894 new Thread() { 14895 @Override 14896 public void run() { 14897 while (true) { 14898 try { 14899 if (installedLatch.await(1, TimeUnit.SECONDS)) { 14900 break; 14901 } 14902 } catch (InterruptedException ignored) { 14903 } 14904 14905 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 14906 final int progress = 10 + (int) MathUtils.constrain( 14907 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 14908 mMoveCallbacks.notifyStatusChanged(moveId, progress); 14909 } 14910 } 14911 }.start(); 14912 14913 final String dataAppName = codeFile.getName(); 14914 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 14915 dataAppName, appId, seinfo); 14916 } else { 14917 move = null; 14918 } 14919 14920 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 14921 14922 final Message msg = mHandler.obtainMessage(INIT_COPY); 14923 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 14924 msg.obj = new InstallParams(origin, move, installObserver, installFlags, 14925 installerPackageName, volumeUuid, null, user, packageAbiOverride); 14926 mHandler.sendMessage(msg); 14927 } 14928 14929 @Override 14930 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 14931 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 14932 14933 final int realMoveId = mNextMoveId.getAndIncrement(); 14934 final Bundle extras = new Bundle(); 14935 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 14936 mMoveCallbacks.notifyCreated(realMoveId, extras); 14937 14938 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 14939 @Override 14940 public void onCreated(int moveId, Bundle extras) { 14941 // Ignored 14942 } 14943 14944 @Override 14945 public void onStatusChanged(int moveId, int status, long estMillis) { 14946 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 14947 } 14948 }; 14949 14950 final StorageManager storage = mContext.getSystemService(StorageManager.class); 14951 storage.setPrimaryStorageUuid(volumeUuid, callback); 14952 return realMoveId; 14953 } 14954 14955 @Override 14956 public int getMoveStatus(int moveId) { 14957 mContext.enforceCallingOrSelfPermission( 14958 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14959 return mMoveCallbacks.mLastStatus.get(moveId); 14960 } 14961 14962 @Override 14963 public void registerMoveCallback(IPackageMoveObserver callback) { 14964 mContext.enforceCallingOrSelfPermission( 14965 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14966 mMoveCallbacks.register(callback); 14967 } 14968 14969 @Override 14970 public void unregisterMoveCallback(IPackageMoveObserver callback) { 14971 mContext.enforceCallingOrSelfPermission( 14972 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 14973 mMoveCallbacks.unregister(callback); 14974 } 14975 14976 @Override 14977 public boolean setInstallLocation(int loc) { 14978 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 14979 null); 14980 if (getInstallLocation() == loc) { 14981 return true; 14982 } 14983 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 14984 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 14985 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 14986 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 14987 return true; 14988 } 14989 return false; 14990 } 14991 14992 @Override 14993 public int getInstallLocation() { 14994 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 14995 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 14996 PackageHelper.APP_INSTALL_AUTO); 14997 } 14998 14999 /** Called by UserManagerService */ 15000 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 15001 mDirtyUsers.remove(userHandle); 15002 mSettings.removeUserLPw(userHandle); 15003 mPendingBroadcasts.remove(userHandle); 15004 if (mInstaller != null) { 15005 // Technically, we shouldn't be doing this with the package lock 15006 // held. However, this is very rare, and there is already so much 15007 // other disk I/O going on, that we'll let it slide for now. 15008 final StorageManager storage = StorageManager.from(mContext); 15009 final List<VolumeInfo> vols = storage.getVolumes(); 15010 for (VolumeInfo vol : vols) { 15011 if (vol.getType() == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) { 15012 final String volumeUuid = vol.getFsUuid(); 15013 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 15014 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 15015 } 15016 } 15017 } 15018 mUserNeedsBadging.delete(userHandle); 15019 removeUnusedPackagesLILPw(userManager, userHandle); 15020 } 15021 15022 /** 15023 * We're removing userHandle and would like to remove any downloaded packages 15024 * that are no longer in use by any other user. 15025 * @param userHandle the user being removed 15026 */ 15027 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 15028 final boolean DEBUG_CLEAN_APKS = false; 15029 int [] users = userManager.getUserIdsLPr(); 15030 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 15031 while (psit.hasNext()) { 15032 PackageSetting ps = psit.next(); 15033 if (ps.pkg == null) { 15034 continue; 15035 } 15036 final String packageName = ps.pkg.packageName; 15037 // Skip over if system app 15038 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 15039 continue; 15040 } 15041 if (DEBUG_CLEAN_APKS) { 15042 Slog.i(TAG, "Checking package " + packageName); 15043 } 15044 boolean keep = false; 15045 for (int i = 0; i < users.length; i++) { 15046 if (users[i] != userHandle && ps.getInstalled(users[i])) { 15047 keep = true; 15048 if (DEBUG_CLEAN_APKS) { 15049 Slog.i(TAG, " Keeping package " + packageName + " for user " 15050 + users[i]); 15051 } 15052 break; 15053 } 15054 } 15055 if (!keep) { 15056 if (DEBUG_CLEAN_APKS) { 15057 Slog.i(TAG, " Removing package " + packageName); 15058 } 15059 mHandler.post(new Runnable() { 15060 public void run() { 15061 deletePackageX(packageName, userHandle, 0); 15062 } //end run 15063 }); 15064 } 15065 } 15066 } 15067 15068 /** Called by UserManagerService */ 15069 void createNewUserLILPw(int userHandle, File path) { 15070 if (mInstaller != null) { 15071 mInstaller.createUserConfig(userHandle); 15072 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 15073 } 15074 } 15075 15076 void newUserCreatedLILPw(int userHandle) { 15077 // Adding a user requires updating runtime permissions for system apps. 15078 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 15079 } 15080 15081 @Override 15082 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 15083 mContext.enforceCallingOrSelfPermission( 15084 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 15085 "Only package verification agents can read the verifier device identity"); 15086 15087 synchronized (mPackages) { 15088 return mSettings.getVerifierDeviceIdentityLPw(); 15089 } 15090 } 15091 15092 @Override 15093 public void setPermissionEnforced(String permission, boolean enforced) { 15094 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 15095 if (READ_EXTERNAL_STORAGE.equals(permission)) { 15096 synchronized (mPackages) { 15097 if (mSettings.mReadExternalStorageEnforced == null 15098 || mSettings.mReadExternalStorageEnforced != enforced) { 15099 mSettings.mReadExternalStorageEnforced = enforced; 15100 mSettings.writeLPr(); 15101 } 15102 } 15103 // kill any non-foreground processes so we restart them and 15104 // grant/revoke the GID. 15105 final IActivityManager am = ActivityManagerNative.getDefault(); 15106 if (am != null) { 15107 final long token = Binder.clearCallingIdentity(); 15108 try { 15109 am.killProcessesBelowForeground("setPermissionEnforcement"); 15110 } catch (RemoteException e) { 15111 } finally { 15112 Binder.restoreCallingIdentity(token); 15113 } 15114 } 15115 } else { 15116 throw new IllegalArgumentException("No selective enforcement for " + permission); 15117 } 15118 } 15119 15120 @Override 15121 @Deprecated 15122 public boolean isPermissionEnforced(String permission) { 15123 return true; 15124 } 15125 15126 @Override 15127 public boolean isStorageLow() { 15128 final long token = Binder.clearCallingIdentity(); 15129 try { 15130 final DeviceStorageMonitorInternal 15131 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 15132 if (dsm != null) { 15133 return dsm.isMemoryLow(); 15134 } else { 15135 return false; 15136 } 15137 } finally { 15138 Binder.restoreCallingIdentity(token); 15139 } 15140 } 15141 15142 @Override 15143 public IPackageInstaller getPackageInstaller() { 15144 return mInstallerService; 15145 } 15146 15147 private boolean userNeedsBadging(int userId) { 15148 int index = mUserNeedsBadging.indexOfKey(userId); 15149 if (index < 0) { 15150 final UserInfo userInfo; 15151 final long token = Binder.clearCallingIdentity(); 15152 try { 15153 userInfo = sUserManager.getUserInfo(userId); 15154 } finally { 15155 Binder.restoreCallingIdentity(token); 15156 } 15157 final boolean b; 15158 if (userInfo != null && userInfo.isManagedProfile()) { 15159 b = true; 15160 } else { 15161 b = false; 15162 } 15163 mUserNeedsBadging.put(userId, b); 15164 return b; 15165 } 15166 return mUserNeedsBadging.valueAt(index); 15167 } 15168 15169 @Override 15170 public KeySet getKeySetByAlias(String packageName, String alias) { 15171 if (packageName == null || alias == null) { 15172 return null; 15173 } 15174 synchronized(mPackages) { 15175 final PackageParser.Package pkg = mPackages.get(packageName); 15176 if (pkg == null) { 15177 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 15178 throw new IllegalArgumentException("Unknown package: " + packageName); 15179 } 15180 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15181 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 15182 } 15183 } 15184 15185 @Override 15186 public KeySet getSigningKeySet(String packageName) { 15187 if (packageName == null) { 15188 return null; 15189 } 15190 synchronized(mPackages) { 15191 final PackageParser.Package pkg = mPackages.get(packageName); 15192 if (pkg == null) { 15193 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 15194 throw new IllegalArgumentException("Unknown package: " + packageName); 15195 } 15196 if (pkg.applicationInfo.uid != Binder.getCallingUid() 15197 && Process.SYSTEM_UID != Binder.getCallingUid()) { 15198 throw new SecurityException("May not access signing KeySet of other apps."); 15199 } 15200 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15201 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 15202 } 15203 } 15204 15205 @Override 15206 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 15207 if (packageName == null || ks == null) { 15208 return false; 15209 } 15210 synchronized(mPackages) { 15211 final PackageParser.Package pkg = mPackages.get(packageName); 15212 if (pkg == null) { 15213 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 15214 throw new IllegalArgumentException("Unknown package: " + packageName); 15215 } 15216 IBinder ksh = ks.getToken(); 15217 if (ksh instanceof KeySetHandle) { 15218 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15219 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 15220 } 15221 return false; 15222 } 15223 } 15224 15225 @Override 15226 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 15227 if (packageName == null || ks == null) { 15228 return false; 15229 } 15230 synchronized(mPackages) { 15231 final PackageParser.Package pkg = mPackages.get(packageName); 15232 if (pkg == null) { 15233 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 15234 throw new IllegalArgumentException("Unknown package: " + packageName); 15235 } 15236 IBinder ksh = ks.getToken(); 15237 if (ksh instanceof KeySetHandle) { 15238 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15239 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 15240 } 15241 return false; 15242 } 15243 } 15244 15245 public void getUsageStatsIfNoPackageUsageInfo() { 15246 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 15247 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 15248 if (usm == null) { 15249 throw new IllegalStateException("UsageStatsManager must be initialized"); 15250 } 15251 long now = System.currentTimeMillis(); 15252 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 15253 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 15254 String packageName = entry.getKey(); 15255 PackageParser.Package pkg = mPackages.get(packageName); 15256 if (pkg == null) { 15257 continue; 15258 } 15259 UsageStats usage = entry.getValue(); 15260 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 15261 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 15262 } 15263 } 15264 } 15265 15266 /** 15267 * Check and throw if the given before/after packages would be considered a 15268 * downgrade. 15269 */ 15270 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 15271 throws PackageManagerException { 15272 if (after.versionCode < before.mVersionCode) { 15273 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 15274 "Update version code " + after.versionCode + " is older than current " 15275 + before.mVersionCode); 15276 } else if (after.versionCode == before.mVersionCode) { 15277 if (after.baseRevisionCode < before.baseRevisionCode) { 15278 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 15279 "Update base revision code " + after.baseRevisionCode 15280 + " is older than current " + before.baseRevisionCode); 15281 } 15282 15283 if (!ArrayUtils.isEmpty(after.splitNames)) { 15284 for (int i = 0; i < after.splitNames.length; i++) { 15285 final String splitName = after.splitNames[i]; 15286 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 15287 if (j != -1) { 15288 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 15289 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 15290 "Update split " + splitName + " revision code " 15291 + after.splitRevisionCodes[i] + " is older than current " 15292 + before.splitRevisionCodes[j]); 15293 } 15294 } 15295 } 15296 } 15297 } 15298 } 15299 15300 private static class MoveCallbacks extends Handler { 15301 private static final int MSG_CREATED = 1; 15302 private static final int MSG_STATUS_CHANGED = 2; 15303 15304 private final RemoteCallbackList<IPackageMoveObserver> 15305 mCallbacks = new RemoteCallbackList<>(); 15306 15307 private final SparseIntArray mLastStatus = new SparseIntArray(); 15308 15309 public MoveCallbacks(Looper looper) { 15310 super(looper); 15311 } 15312 15313 public void register(IPackageMoveObserver callback) { 15314 mCallbacks.register(callback); 15315 } 15316 15317 public void unregister(IPackageMoveObserver callback) { 15318 mCallbacks.unregister(callback); 15319 } 15320 15321 @Override 15322 public void handleMessage(Message msg) { 15323 final SomeArgs args = (SomeArgs) msg.obj; 15324 final int n = mCallbacks.beginBroadcast(); 15325 for (int i = 0; i < n; i++) { 15326 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 15327 try { 15328 invokeCallback(callback, msg.what, args); 15329 } catch (RemoteException ignored) { 15330 } 15331 } 15332 mCallbacks.finishBroadcast(); 15333 args.recycle(); 15334 } 15335 15336 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 15337 throws RemoteException { 15338 switch (what) { 15339 case MSG_CREATED: { 15340 callback.onCreated(args.argi1, (Bundle) args.arg2); 15341 break; 15342 } 15343 case MSG_STATUS_CHANGED: { 15344 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 15345 break; 15346 } 15347 } 15348 } 15349 15350 private void notifyCreated(int moveId, Bundle extras) { 15351 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 15352 15353 final SomeArgs args = SomeArgs.obtain(); 15354 args.argi1 = moveId; 15355 args.arg2 = extras; 15356 obtainMessage(MSG_CREATED, args).sendToTarget(); 15357 } 15358 15359 private void notifyStatusChanged(int moveId, int status) { 15360 notifyStatusChanged(moveId, status, -1); 15361 } 15362 15363 private void notifyStatusChanged(int moveId, int status, long estMillis) { 15364 Slog.v(TAG, "Move " + moveId + " status " + status); 15365 15366 final SomeArgs args = SomeArgs.obtain(); 15367 args.argi1 = moveId; 15368 args.argi2 = status; 15369 args.arg3 = estMillis; 15370 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 15371 15372 synchronized (mLastStatus) { 15373 mLastStatus.put(moveId, status); 15374 } 15375 } 15376 } 15377 15378 private final class OnPermissionChangeListeners extends Handler { 15379 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 15380 15381 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 15382 new RemoteCallbackList<>(); 15383 15384 public OnPermissionChangeListeners(Looper looper) { 15385 super(looper); 15386 } 15387 15388 @Override 15389 public void handleMessage(Message msg) { 15390 switch (msg.what) { 15391 case MSG_ON_PERMISSIONS_CHANGED: { 15392 final int uid = msg.arg1; 15393 handleOnPermissionsChanged(uid); 15394 } break; 15395 } 15396 } 15397 15398 public void addListenerLocked(IOnPermissionsChangeListener listener) { 15399 mPermissionListeners.register(listener); 15400 15401 } 15402 15403 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 15404 mPermissionListeners.unregister(listener); 15405 } 15406 15407 public void onPermissionsChanged(int uid) { 15408 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 15409 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 15410 } 15411 } 15412 15413 private void handleOnPermissionsChanged(int uid) { 15414 final int count = mPermissionListeners.beginBroadcast(); 15415 try { 15416 for (int i = 0; i < count; i++) { 15417 IOnPermissionsChangeListener callback = mPermissionListeners 15418 .getBroadcastItem(i); 15419 try { 15420 callback.onPermissionsChanged(uid); 15421 } catch (RemoteException e) { 15422 Log.e(TAG, "Permission listener is dead", e); 15423 } 15424 } 15425 } finally { 15426 mPermissionListeners.finishBroadcast(); 15427 } 15428 } 15429 } 15430} 15431