PackageManagerService.java revision 2f5811dcfd840e149851a9333e27ef3cdddf7a46
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.DELETE_PACKAGES; 20import static android.Manifest.permission.INSTALL_PACKAGES; 21import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 22import static android.Manifest.permission.REQUEST_DELETE_PACKAGES; 23import static android.Manifest.permission.REQUEST_INSTALL_PACKAGES; 24import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 25import static android.Manifest.permission.WRITE_MEDIA_STORAGE; 26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 31import static android.content.pm.PackageManager.DELETE_KEEP_DATA; 32import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 33import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 36import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 39import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 40import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 41import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 44import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID; 45import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 46import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 49import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 50import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 51import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 52import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 53import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 54import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 55import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 56import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 57import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 58import static android.content.pm.PackageManager.INSTALL_INTERNAL; 59import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 65import static android.content.pm.PackageManager.MATCH_ALL; 66import static android.content.pm.PackageManager.MATCH_ANY_USER; 67import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 68import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 70import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 71import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; 72import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES; 73import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 74import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 75import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL; 76import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 77import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 78import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 79import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 80import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 81import static android.content.pm.PackageManager.PERMISSION_DENIED; 82import static android.content.pm.PackageManager.PERMISSION_GRANTED; 83import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 84import static android.content.pm.PackageParser.isApkFile; 85import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 86import static android.system.OsConstants.O_CREAT; 87import static android.system.OsConstants.O_RDWR; 88import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 89import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 90import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 91import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 92import static com.android.internal.util.ArrayUtils.appendInt; 93import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 94import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 95import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 96import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 97import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 98import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 99import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 100import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter; 102import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 103import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 104import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 105 106import android.Manifest; 107import android.annotation.NonNull; 108import android.annotation.Nullable; 109import android.app.ActivityManager; 110import android.app.AppOpsManager; 111import android.app.IActivityManager; 112import android.app.ResourcesManager; 113import android.app.admin.IDevicePolicyManager; 114import android.app.admin.SecurityLog; 115import android.app.backup.IBackupManager; 116import android.content.BroadcastReceiver; 117import android.content.ComponentName; 118import android.content.ContentResolver; 119import android.content.Context; 120import android.content.IIntentReceiver; 121import android.content.Intent; 122import android.content.IntentFilter; 123import android.content.IntentSender; 124import android.content.IntentSender.SendIntentException; 125import android.content.ServiceConnection; 126import android.content.pm.ActivityInfo; 127import android.content.pm.ApplicationInfo; 128import android.content.pm.AppsQueryHelper; 129import android.content.pm.ComponentInfo; 130import android.content.pm.InstantAppInfo; 131import android.content.pm.EphemeralRequest; 132import android.content.pm.EphemeralResolveInfo; 133import android.content.pm.EphemeralResponse; 134import android.content.pm.FallbackCategoryProvider; 135import android.content.pm.FeatureInfo; 136import android.content.pm.IOnPermissionsChangeListener; 137import android.content.pm.IPackageDataObserver; 138import android.content.pm.IPackageDeleteObserver; 139import android.content.pm.IPackageDeleteObserver2; 140import android.content.pm.IPackageInstallObserver2; 141import android.content.pm.IPackageInstaller; 142import android.content.pm.IPackageManager; 143import android.content.pm.IPackageMoveObserver; 144import android.content.pm.IPackageStatsObserver; 145import android.content.pm.InstrumentationInfo; 146import android.content.pm.IntentFilterVerificationInfo; 147import android.content.pm.KeySet; 148import android.content.pm.PackageCleanItem; 149import android.content.pm.PackageInfo; 150import android.content.pm.PackageInfoLite; 151import android.content.pm.PackageInstaller; 152import android.content.pm.PackageManager; 153import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 154import android.content.pm.PackageManagerInternal; 155import android.content.pm.PackageParser; 156import android.content.pm.PackageParser.ActivityIntentInfo; 157import android.content.pm.PackageParser.PackageLite; 158import android.content.pm.PackageParser.PackageParserException; 159import android.content.pm.PackageStats; 160import android.content.pm.PackageUserState; 161import android.content.pm.ParceledListSlice; 162import android.content.pm.PermissionGroupInfo; 163import android.content.pm.PermissionInfo; 164import android.content.pm.ProviderInfo; 165import android.content.pm.ResolveInfo; 166import android.content.pm.SELinuxUtil; 167import android.content.pm.ServiceInfo; 168import android.content.pm.SharedLibraryInfo; 169import android.content.pm.Signature; 170import android.content.pm.UserInfo; 171import android.content.pm.VerifierDeviceIdentity; 172import android.content.pm.VerifierInfo; 173import android.content.pm.VersionedPackage; 174import android.content.res.Resources; 175import android.graphics.Bitmap; 176import android.hardware.display.DisplayManager; 177import android.net.Uri; 178import android.os.Binder; 179import android.os.Build; 180import android.os.Bundle; 181import android.os.Debug; 182import android.os.Environment; 183import android.os.Environment.UserEnvironment; 184import android.os.FileUtils; 185import android.os.Handler; 186import android.os.IBinder; 187import android.os.Looper; 188import android.os.Message; 189import android.os.Parcel; 190import android.os.ParcelFileDescriptor; 191import android.os.PatternMatcher; 192import android.os.Process; 193import android.os.RemoteCallbackList; 194import android.os.RemoteException; 195import android.os.ResultReceiver; 196import android.os.SELinux; 197import android.os.ServiceManager; 198import android.os.ShellCallback; 199import android.os.SystemClock; 200import android.os.SystemProperties; 201import android.os.Trace; 202import android.os.UserHandle; 203import android.os.UserManager; 204import android.os.UserManagerInternal; 205import android.os.storage.IStorageManager; 206import android.os.storage.StorageManagerInternal; 207import android.os.storage.StorageEventListener; 208import android.os.storage.StorageManager; 209import android.os.storage.VolumeInfo; 210import android.os.storage.VolumeRecord; 211import android.provider.Settings.Global; 212import android.provider.Settings.Secure; 213import android.security.KeyStore; 214import android.security.SystemKeyStore; 215import android.system.ErrnoException; 216import android.system.Os; 217import android.text.TextUtils; 218import android.text.format.DateUtils; 219import android.util.ArrayMap; 220import android.util.ArraySet; 221import android.util.Base64; 222import android.util.DisplayMetrics; 223import android.util.EventLog; 224import android.util.ExceptionUtils; 225import android.util.Log; 226import android.util.LogPrinter; 227import android.util.MathUtils; 228import android.util.PackageUtils; 229import android.util.Pair; 230import android.util.PrintStreamPrinter; 231import android.util.Slog; 232import android.util.SparseArray; 233import android.util.SparseBooleanArray; 234import android.util.SparseIntArray; 235import android.util.Xml; 236import android.util.jar.StrictJarFile; 237import android.view.Display; 238 239import com.android.internal.R; 240import com.android.internal.annotations.GuardedBy; 241import com.android.internal.app.IMediaContainerService; 242import com.android.internal.app.ResolverActivity; 243import com.android.internal.content.NativeLibraryHelper; 244import com.android.internal.content.PackageHelper; 245import com.android.internal.logging.MetricsLogger; 246import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 247import com.android.internal.os.IParcelFileDescriptorFactory; 248import com.android.internal.os.RoSystemProperties; 249import com.android.internal.os.SomeArgs; 250import com.android.internal.os.Zygote; 251import com.android.internal.telephony.CarrierAppUtils; 252import com.android.internal.util.ArrayUtils; 253import com.android.internal.util.FastPrintWriter; 254import com.android.internal.util.FastXmlSerializer; 255import com.android.internal.util.IndentingPrintWriter; 256import com.android.internal.util.Preconditions; 257import com.android.internal.util.XmlUtils; 258import com.android.server.AttributeCache; 259import com.android.server.BackgroundDexOptJobService; 260import com.android.server.EventLogTags; 261import com.android.server.FgThread; 262import com.android.server.IntentResolver; 263import com.android.server.LocalServices; 264import com.android.server.ServiceThread; 265import com.android.server.SystemConfig; 266import com.android.server.Watchdog; 267import com.android.server.net.NetworkPolicyManagerInternal; 268import com.android.server.pm.Installer.InstallerException; 269import com.android.server.pm.PermissionsState.PermissionState; 270import com.android.server.pm.Settings.DatabaseVersion; 271import com.android.server.pm.Settings.VersionInfo; 272import com.android.server.pm.dex.DexManager; 273import com.android.server.storage.DeviceStorageMonitorInternal; 274 275import dalvik.system.CloseGuard; 276import dalvik.system.DexFile; 277import dalvik.system.VMRuntime; 278 279import libcore.io.IoUtils; 280import libcore.util.EmptyArray; 281 282import org.xmlpull.v1.XmlPullParser; 283import org.xmlpull.v1.XmlPullParserException; 284import org.xmlpull.v1.XmlSerializer; 285 286import java.io.BufferedOutputStream; 287import java.io.BufferedReader; 288import java.io.ByteArrayInputStream; 289import java.io.ByteArrayOutputStream; 290import java.io.File; 291import java.io.FileDescriptor; 292import java.io.FileInputStream; 293import java.io.FileNotFoundException; 294import java.io.FileOutputStream; 295import java.io.FileReader; 296import java.io.FilenameFilter; 297import java.io.IOException; 298import java.io.PrintWriter; 299import java.nio.charset.StandardCharsets; 300import java.security.DigestInputStream; 301import java.security.MessageDigest; 302import java.security.NoSuchAlgorithmException; 303import java.security.PublicKey; 304import java.security.SecureRandom; 305import java.security.cert.Certificate; 306import java.security.cert.CertificateEncodingException; 307import java.security.cert.CertificateException; 308import java.text.SimpleDateFormat; 309import java.util.ArrayList; 310import java.util.Arrays; 311import java.util.Collection; 312import java.util.Collections; 313import java.util.Comparator; 314import java.util.Date; 315import java.util.HashSet; 316import java.util.HashMap; 317import java.util.Iterator; 318import java.util.List; 319import java.util.Map; 320import java.util.Objects; 321import java.util.Set; 322import java.util.concurrent.CountDownLatch; 323import java.util.concurrent.TimeUnit; 324import java.util.concurrent.atomic.AtomicBoolean; 325import java.util.concurrent.atomic.AtomicInteger; 326 327/** 328 * Keep track of all those APKs everywhere. 329 * <p> 330 * Internally there are two important locks: 331 * <ul> 332 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 333 * and other related state. It is a fine-grained lock that should only be held 334 * momentarily, as it's one of the most contended locks in the system. 335 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 336 * operations typically involve heavy lifting of application data on disk. Since 337 * {@code installd} is single-threaded, and it's operations can often be slow, 338 * this lock should never be acquired while already holding {@link #mPackages}. 339 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 340 * holding {@link #mInstallLock}. 341 * </ul> 342 * Many internal methods rely on the caller to hold the appropriate locks, and 343 * this contract is expressed through method name suffixes: 344 * <ul> 345 * <li>fooLI(): the caller must hold {@link #mInstallLock} 346 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 347 * being modified must be frozen 348 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 349 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 350 * </ul> 351 * <p> 352 * Because this class is very central to the platform's security; please run all 353 * CTS and unit tests whenever making modifications: 354 * 355 * <pre> 356 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 357 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases 358 * </pre> 359 */ 360public class PackageManagerService extends IPackageManager.Stub { 361 static final String TAG = "PackageManager"; 362 static final boolean DEBUG_SETTINGS = false; 363 static final boolean DEBUG_PREFERRED = false; 364 static final boolean DEBUG_UPGRADE = false; 365 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 366 private static final boolean DEBUG_BACKUP = false; 367 private static final boolean DEBUG_INSTALL = false; 368 private static final boolean DEBUG_REMOVE = false; 369 private static final boolean DEBUG_BROADCASTS = false; 370 private static final boolean DEBUG_SHOW_INFO = false; 371 private static final boolean DEBUG_PACKAGE_INFO = false; 372 private static final boolean DEBUG_INTENT_MATCHING = false; 373 private static final boolean DEBUG_PACKAGE_SCANNING = false; 374 private static final boolean DEBUG_VERIFY = false; 375 private static final boolean DEBUG_FILTERS = false; 376 377 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 378 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 379 // user, but by default initialize to this. 380 public static final boolean DEBUG_DEXOPT = false; 381 382 private static final boolean DEBUG_ABI_SELECTION = false; 383 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 384 private static final boolean DEBUG_TRIAGED_MISSING = false; 385 private static final boolean DEBUG_APP_DATA = false; 386 387 /** REMOVE. According to Svet, this was only used to reset permissions during development. */ 388 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 389 390 private static final boolean DISABLE_EPHEMERAL_APPS = false; 391 private static final boolean HIDE_EPHEMERAL_APIS = false; 392 393 private static final boolean ENABLE_QUOTA = 394 SystemProperties.getBoolean("persist.fw.quota", false); 395 396 private static final int RADIO_UID = Process.PHONE_UID; 397 private static final int LOG_UID = Process.LOG_UID; 398 private static final int NFC_UID = Process.NFC_UID; 399 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 400 private static final int SHELL_UID = Process.SHELL_UID; 401 402 // Cap the size of permission trees that 3rd party apps can define 403 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 404 405 // Suffix used during package installation when copying/moving 406 // package apks to install directory. 407 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 408 409 static final int SCAN_NO_DEX = 1<<1; 410 static final int SCAN_FORCE_DEX = 1<<2; 411 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 412 static final int SCAN_NEW_INSTALL = 1<<4; 413 static final int SCAN_UPDATE_TIME = 1<<5; 414 static final int SCAN_BOOTING = 1<<6; 415 static final int SCAN_TRUSTED_OVERLAY = 1<<7; 416 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8; 417 static final int SCAN_REPLACING = 1<<9; 418 static final int SCAN_REQUIRE_KNOWN = 1<<10; 419 static final int SCAN_MOVE = 1<<11; 420 static final int SCAN_INITIAL = 1<<12; 421 static final int SCAN_CHECK_ONLY = 1<<13; 422 static final int SCAN_DONT_KILL_APP = 1<<14; 423 static final int SCAN_IGNORE_FROZEN = 1<<15; 424 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16; 425 static final int SCAN_AS_INSTANT_APP = 1<<17; 426 static final int SCAN_AS_FULL_APP = 1<<18; 427 /** Should not be with the scan flags */ 428 static final int FLAGS_REMOVE_CHATTY = 1<<31; 429 430 private static final String STATIC_SHARED_LIB_DELIMITER = "_"; 431 432 private static final int[] EMPTY_INT_ARRAY = new int[0]; 433 434 /** 435 * Timeout (in milliseconds) after which the watchdog should declare that 436 * our handler thread is wedged. The usual default for such things is one 437 * minute but we sometimes do very lengthy I/O operations on this thread, 438 * such as installing multi-gigabyte applications, so ours needs to be longer. 439 */ 440 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 441 442 /** 443 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 444 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 445 * settings entry if available, otherwise we use the hardcoded default. If it's been 446 * more than this long since the last fstrim, we force one during the boot sequence. 447 * 448 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 449 * one gets run at the next available charging+idle time. This final mandatory 450 * no-fstrim check kicks in only of the other scheduling criteria is never met. 451 */ 452 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 453 454 /** 455 * Whether verification is enabled by default. 456 */ 457 private static final boolean DEFAULT_VERIFY_ENABLE = true; 458 459 /** 460 * The default maximum time to wait for the verification agent to return in 461 * milliseconds. 462 */ 463 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 464 465 /** 466 * The default response for package verification timeout. 467 * 468 * This can be either PackageManager.VERIFICATION_ALLOW or 469 * PackageManager.VERIFICATION_REJECT. 470 */ 471 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 472 473 static final String PLATFORM_PACKAGE_NAME = "android"; 474 475 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 476 477 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 478 DEFAULT_CONTAINER_PACKAGE, 479 "com.android.defcontainer.DefaultContainerService"); 480 481 private static final String KILL_APP_REASON_GIDS_CHANGED = 482 "permission grant or revoke changed gids"; 483 484 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 485 "permissions revoked"; 486 487 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 488 489 private static final String PACKAGE_SCHEME = "package"; 490 491 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 492 /** 493 * If VENDOR_OVERLAY_THEME_PROPERTY is set, search for runtime resource overlay APKs also in 494 * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_THEME_PROPERTY> in addition to 495 * VENDOR_OVERLAY_DIR. 496 */ 497 private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme"; 498 /** 499 * Same as VENDOR_OVERLAY_THEME_PROPERTY, except persistent. If set will override whatever 500 * is in VENDOR_OVERLAY_THEME_PROPERTY. 501 */ 502 private static final String VENDOR_OVERLAY_THEME_PERSIST_PROPERTY 503 = "persist.vendor.overlay.theme"; 504 505 /** Permission grant: not grant the permission. */ 506 private static final int GRANT_DENIED = 1; 507 508 /** Permission grant: grant the permission as an install permission. */ 509 private static final int GRANT_INSTALL = 2; 510 511 /** Permission grant: grant the permission as a runtime one. */ 512 private static final int GRANT_RUNTIME = 3; 513 514 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 515 private static final int GRANT_UPGRADE = 4; 516 517 /** Canonical intent used to identify what counts as a "web browser" app */ 518 private static final Intent sBrowserIntent; 519 static { 520 sBrowserIntent = new Intent(); 521 sBrowserIntent.setAction(Intent.ACTION_VIEW); 522 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 523 sBrowserIntent.setData(Uri.parse("http:")); 524 } 525 526 /** 527 * The set of all protected actions [i.e. those actions for which a high priority 528 * intent filter is disallowed]. 529 */ 530 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 531 static { 532 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 533 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 534 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 535 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 536 } 537 538 // Compilation reasons. 539 public static final int REASON_FIRST_BOOT = 0; 540 public static final int REASON_BOOT = 1; 541 public static final int REASON_INSTALL = 2; 542 public static final int REASON_BACKGROUND_DEXOPT = 3; 543 public static final int REASON_AB_OTA = 4; 544 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 545 public static final int REASON_SHARED_APK = 6; 546 public static final int REASON_FORCED_DEXOPT = 7; 547 public static final int REASON_CORE_APP = 8; 548 549 public static final int REASON_LAST = REASON_CORE_APP; 550 551 /** Special library name that skips shared libraries check during compilation. */ 552 private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; 553 554 /** All dangerous permission names in the same order as the events in MetricsEvent */ 555 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList( 556 Manifest.permission.READ_CALENDAR, 557 Manifest.permission.WRITE_CALENDAR, 558 Manifest.permission.CAMERA, 559 Manifest.permission.READ_CONTACTS, 560 Manifest.permission.WRITE_CONTACTS, 561 Manifest.permission.GET_ACCOUNTS, 562 Manifest.permission.ACCESS_FINE_LOCATION, 563 Manifest.permission.ACCESS_COARSE_LOCATION, 564 Manifest.permission.RECORD_AUDIO, 565 Manifest.permission.READ_PHONE_STATE, 566 Manifest.permission.CALL_PHONE, 567 Manifest.permission.READ_CALL_LOG, 568 Manifest.permission.WRITE_CALL_LOG, 569 Manifest.permission.ADD_VOICEMAIL, 570 Manifest.permission.USE_SIP, 571 Manifest.permission.PROCESS_OUTGOING_CALLS, 572 Manifest.permission.READ_CELL_BROADCASTS, 573 Manifest.permission.BODY_SENSORS, 574 Manifest.permission.SEND_SMS, 575 Manifest.permission.RECEIVE_SMS, 576 Manifest.permission.READ_SMS, 577 Manifest.permission.RECEIVE_WAP_PUSH, 578 Manifest.permission.RECEIVE_MMS, 579 Manifest.permission.READ_EXTERNAL_STORAGE, 580 Manifest.permission.WRITE_EXTERNAL_STORAGE, 581 Manifest.permission.READ_PHONE_NUMBER); 582 583 584 /** 585 * Version number for the package parser cache. Increment this whenever the format or 586 * extent of cached data changes. See {@code PackageParser#setCacheDir}. 587 */ 588 private static final String PACKAGE_PARSER_CACHE_VERSION = "1"; 589 590 /** 591 * Whether the package parser cache is enabled. 592 */ 593 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true; 594 595 final ServiceThread mHandlerThread; 596 597 final PackageHandler mHandler; 598 599 private final ProcessLoggingHandler mProcessLoggingHandler; 600 601 /** 602 * Messages for {@link #mHandler} that need to wait for system ready before 603 * being dispatched. 604 */ 605 private ArrayList<Message> mPostSystemReadyMessages; 606 607 final int mSdkVersion = Build.VERSION.SDK_INT; 608 609 final Context mContext; 610 final boolean mFactoryTest; 611 final boolean mOnlyCore; 612 final DisplayMetrics mMetrics; 613 final int mDefParseFlags; 614 final String[] mSeparateProcesses; 615 final boolean mIsUpgrade; 616 final boolean mIsPreNUpgrade; 617 final boolean mIsPreNMR1Upgrade; 618 619 @GuardedBy("mPackages") 620 private boolean mDexOptDialogShown; 621 622 /** The location for ASEC container files on internal storage. */ 623 final String mAsecInternalPath; 624 625 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 626 // LOCK HELD. Can be called with mInstallLock held. 627 @GuardedBy("mInstallLock") 628 final Installer mInstaller; 629 630 /** Directory where installed third-party apps stored */ 631 final File mAppInstallDir; 632 final File mEphemeralInstallDir; 633 634 /** 635 * Directory to which applications installed internally have their 636 * 32 bit native libraries copied. 637 */ 638 private File mAppLib32InstallDir; 639 640 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 641 // apps. 642 final File mDrmAppPrivateInstallDir; 643 644 // ---------------------------------------------------------------- 645 646 // Lock for state used when installing and doing other long running 647 // operations. Methods that must be called with this lock held have 648 // the suffix "LI". 649 final Object mInstallLock = new Object(); 650 651 // ---------------------------------------------------------------- 652 653 // Keys are String (package name), values are Package. This also serves 654 // as the lock for the global state. Methods that must be called with 655 // this lock held have the prefix "LP". 656 @GuardedBy("mPackages") 657 final ArrayMap<String, PackageParser.Package> mPackages = 658 new ArrayMap<String, PackageParser.Package>(); 659 660 final ArrayMap<String, Set<String>> mKnownCodebase = 661 new ArrayMap<String, Set<String>>(); 662 663 // Tracks available target package names -> overlay package paths. 664 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 665 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 666 667 /** 668 * Tracks new system packages [received in an OTA] that we expect to 669 * find updated user-installed versions. Keys are package name, values 670 * are package location. 671 */ 672 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 673 /** 674 * Tracks high priority intent filters for protected actions. During boot, certain 675 * filter actions are protected and should never be allowed to have a high priority 676 * intent filter for them. However, there is one, and only one exception -- the 677 * setup wizard. It must be able to define a high priority intent filter for these 678 * actions to ensure there are no escapes from the wizard. We need to delay processing 679 * of these during boot as we need to look at all of the system packages in order 680 * to know which component is the setup wizard. 681 */ 682 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 683 /** 684 * Whether or not processing protected filters should be deferred. 685 */ 686 private boolean mDeferProtectedFilters = true; 687 688 /** 689 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 690 */ 691 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 692 /** 693 * Whether or not system app permissions should be promoted from install to runtime. 694 */ 695 boolean mPromoteSystemApps; 696 697 @GuardedBy("mPackages") 698 final Settings mSettings; 699 700 /** 701 * Set of package names that are currently "frozen", which means active 702 * surgery is being done on the code/data for that package. The platform 703 * will refuse to launch frozen packages to avoid race conditions. 704 * 705 * @see PackageFreezer 706 */ 707 @GuardedBy("mPackages") 708 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 709 710 final ProtectedPackages mProtectedPackages; 711 712 boolean mFirstBoot; 713 714 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy; 715 716 // System configuration read by SystemConfig. 717 final int[] mGlobalGids; 718 final SparseArray<ArraySet<String>> mSystemPermissions; 719 @GuardedBy("mAvailableFeatures") 720 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 721 722 // If mac_permissions.xml was found for seinfo labeling. 723 boolean mFoundPolicyFile; 724 725 private final InstantAppRegistry mInstantAppRegistry; 726 727 public static final class SharedLibraryEntry { 728 public final String path; 729 public final String apk; 730 public final SharedLibraryInfo info; 731 732 SharedLibraryEntry(String _path, String _apk, String name, int version, int type, 733 String declaringPackageName, int declaringPackageVersionCode) { 734 path = _path; 735 apk = _apk; 736 info = new SharedLibraryInfo(name, version, type, new VersionedPackage( 737 declaringPackageName, declaringPackageVersionCode), null); 738 } 739 } 740 741 // Currently known shared libraries. 742 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>(); 743 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage = 744 new ArrayMap<>(); 745 746 // All available activities, for your resolving pleasure. 747 final ActivityIntentResolver mActivities = 748 new ActivityIntentResolver(); 749 750 // All available receivers, for your resolving pleasure. 751 final ActivityIntentResolver mReceivers = 752 new ActivityIntentResolver(); 753 754 // All available services, for your resolving pleasure. 755 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 756 757 // All available providers, for your resolving pleasure. 758 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 759 760 // Mapping from provider base names (first directory in content URI codePath) 761 // to the provider information. 762 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 763 new ArrayMap<String, PackageParser.Provider>(); 764 765 // Mapping from instrumentation class names to info about them. 766 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 767 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 768 769 // Mapping from permission names to info about them. 770 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 771 new ArrayMap<String, PackageParser.PermissionGroup>(); 772 773 // Packages whose data we have transfered into another package, thus 774 // should no longer exist. 775 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 776 777 // Broadcast actions that are only available to the system. 778 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 779 780 /** List of packages waiting for verification. */ 781 final SparseArray<PackageVerificationState> mPendingVerification 782 = new SparseArray<PackageVerificationState>(); 783 784 /** Set of packages associated with each app op permission. */ 785 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 786 787 final PackageInstallerService mInstallerService; 788 789 private final PackageDexOptimizer mPackageDexOptimizer; 790 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package 791 // is used by other apps). 792 private final DexManager mDexManager; 793 794 private AtomicInteger mNextMoveId = new AtomicInteger(); 795 private final MoveCallbacks mMoveCallbacks; 796 797 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 798 799 // Cache of users who need badging. 800 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 801 802 /** Token for keys in mPendingVerification. */ 803 private int mPendingVerificationToken = 0; 804 805 volatile boolean mSystemReady; 806 volatile boolean mSafeMode; 807 volatile boolean mHasSystemUidErrors; 808 809 ApplicationInfo mAndroidApplication; 810 final ActivityInfo mResolveActivity = new ActivityInfo(); 811 final ResolveInfo mResolveInfo = new ResolveInfo(); 812 ComponentName mResolveComponentName; 813 PackageParser.Package mPlatformPackage; 814 ComponentName mCustomResolverComponentName; 815 816 boolean mResolverReplaced = false; 817 818 private final @Nullable ComponentName mIntentFilterVerifierComponent; 819 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 820 821 private int mIntentFilterVerificationToken = 0; 822 823 /** The service connection to the ephemeral resolver */ 824 final EphemeralResolverConnection mEphemeralResolverConnection; 825 826 /** Component used to install ephemeral applications */ 827 ComponentName mEphemeralInstallerComponent; 828 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 829 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 830 831 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 832 = new SparseArray<IntentFilterVerificationState>(); 833 834 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; 835 836 // List of packages names to keep cached, even if they are uninstalled for all users 837 private List<String> mKeepUninstalledPackages; 838 839 private UserManagerInternal mUserManagerInternal; 840 841 private File mCacheDir; 842 843 private ArraySet<String> mPrivappPermissionsViolations; 844 845 private static class IFVerificationParams { 846 PackageParser.Package pkg; 847 boolean replacing; 848 int userId; 849 int verifierUid; 850 851 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 852 int _userId, int _verifierUid) { 853 pkg = _pkg; 854 replacing = _replacing; 855 userId = _userId; 856 replacing = _replacing; 857 verifierUid = _verifierUid; 858 } 859 } 860 861 private interface IntentFilterVerifier<T extends IntentFilter> { 862 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 863 T filter, String packageName); 864 void startVerifications(int userId); 865 void receiveVerificationResponse(int verificationId); 866 } 867 868 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 869 private Context mContext; 870 private ComponentName mIntentFilterVerifierComponent; 871 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 872 873 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 874 mContext = context; 875 mIntentFilterVerifierComponent = verifierComponent; 876 } 877 878 private String getDefaultScheme() { 879 return IntentFilter.SCHEME_HTTPS; 880 } 881 882 @Override 883 public void startVerifications(int userId) { 884 // Launch verifications requests 885 int count = mCurrentIntentFilterVerifications.size(); 886 for (int n=0; n<count; n++) { 887 int verificationId = mCurrentIntentFilterVerifications.get(n); 888 final IntentFilterVerificationState ivs = 889 mIntentFilterVerificationStates.get(verificationId); 890 891 String packageName = ivs.getPackageName(); 892 893 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 894 final int filterCount = filters.size(); 895 ArraySet<String> domainsSet = new ArraySet<>(); 896 for (int m=0; m<filterCount; m++) { 897 PackageParser.ActivityIntentInfo filter = filters.get(m); 898 domainsSet.addAll(filter.getHostsList()); 899 } 900 synchronized (mPackages) { 901 if (mSettings.createIntentFilterVerificationIfNeededLPw( 902 packageName, domainsSet) != null) { 903 scheduleWriteSettingsLocked(); 904 } 905 } 906 sendVerificationRequest(userId, verificationId, ivs); 907 } 908 mCurrentIntentFilterVerifications.clear(); 909 } 910 911 private void sendVerificationRequest(int userId, int verificationId, 912 IntentFilterVerificationState ivs) { 913 914 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 915 verificationIntent.putExtra( 916 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 917 verificationId); 918 verificationIntent.putExtra( 919 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 920 getDefaultScheme()); 921 verificationIntent.putExtra( 922 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 923 ivs.getHostsString()); 924 verificationIntent.putExtra( 925 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 926 ivs.getPackageName()); 927 verificationIntent.setComponent(mIntentFilterVerifierComponent); 928 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 929 930 UserHandle user = new UserHandle(userId); 931 mContext.sendBroadcastAsUser(verificationIntent, user); 932 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 933 "Sending IntentFilter verification broadcast"); 934 } 935 936 public void receiveVerificationResponse(int verificationId) { 937 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 938 939 final boolean verified = ivs.isVerified(); 940 941 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 942 final int count = filters.size(); 943 if (DEBUG_DOMAIN_VERIFICATION) { 944 Slog.i(TAG, "Received verification response " + verificationId 945 + " for " + count + " filters, verified=" + verified); 946 } 947 for (int n=0; n<count; n++) { 948 PackageParser.ActivityIntentInfo filter = filters.get(n); 949 filter.setVerified(verified); 950 951 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 952 + " verified with result:" + verified + " and hosts:" 953 + ivs.getHostsString()); 954 } 955 956 mIntentFilterVerificationStates.remove(verificationId); 957 958 final String packageName = ivs.getPackageName(); 959 IntentFilterVerificationInfo ivi = null; 960 961 synchronized (mPackages) { 962 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 963 } 964 if (ivi == null) { 965 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 966 + verificationId + " packageName:" + packageName); 967 return; 968 } 969 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 970 "Updating IntentFilterVerificationInfo for package " + packageName 971 +" verificationId:" + verificationId); 972 973 synchronized (mPackages) { 974 if (verified) { 975 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 976 } else { 977 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 978 } 979 scheduleWriteSettingsLocked(); 980 981 final int userId = ivs.getUserId(); 982 if (userId != UserHandle.USER_ALL) { 983 final int userStatus = 984 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 985 986 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 987 boolean needUpdate = false; 988 989 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 990 // already been set by the User thru the Disambiguation dialog 991 switch (userStatus) { 992 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 993 if (verified) { 994 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 995 } else { 996 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 997 } 998 needUpdate = true; 999 break; 1000 1001 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 1002 if (verified) { 1003 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 1004 needUpdate = true; 1005 } 1006 break; 1007 1008 default: 1009 // Nothing to do 1010 } 1011 1012 if (needUpdate) { 1013 mSettings.updateIntentFilterVerificationStatusLPw( 1014 packageName, updatedStatus, userId); 1015 scheduleWritePackageRestrictionsLocked(userId); 1016 } 1017 } 1018 } 1019 } 1020 1021 @Override 1022 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 1023 ActivityIntentInfo filter, String packageName) { 1024 if (!hasValidDomains(filter)) { 1025 return false; 1026 } 1027 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 1028 if (ivs == null) { 1029 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 1030 packageName); 1031 } 1032 if (DEBUG_DOMAIN_VERIFICATION) { 1033 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 1034 } 1035 ivs.addFilter(filter); 1036 return true; 1037 } 1038 1039 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 1040 int userId, int verificationId, String packageName) { 1041 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 1042 verifierUid, userId, packageName); 1043 ivs.setPendingState(); 1044 synchronized (mPackages) { 1045 mIntentFilterVerificationStates.append(verificationId, ivs); 1046 mCurrentIntentFilterVerifications.add(verificationId); 1047 } 1048 return ivs; 1049 } 1050 } 1051 1052 private static boolean hasValidDomains(ActivityIntentInfo filter) { 1053 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 1054 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 1055 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 1056 } 1057 1058 // Set of pending broadcasts for aggregating enable/disable of components. 1059 static class PendingPackageBroadcasts { 1060 // for each user id, a map of <package name -> components within that package> 1061 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 1062 1063 public PendingPackageBroadcasts() { 1064 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 1065 } 1066 1067 public ArrayList<String> get(int userId, String packageName) { 1068 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1069 return packages.get(packageName); 1070 } 1071 1072 public void put(int userId, String packageName, ArrayList<String> components) { 1073 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1074 packages.put(packageName, components); 1075 } 1076 1077 public void remove(int userId, String packageName) { 1078 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 1079 if (packages != null) { 1080 packages.remove(packageName); 1081 } 1082 } 1083 1084 public void remove(int userId) { 1085 mUidMap.remove(userId); 1086 } 1087 1088 public int userIdCount() { 1089 return mUidMap.size(); 1090 } 1091 1092 public int userIdAt(int n) { 1093 return mUidMap.keyAt(n); 1094 } 1095 1096 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 1097 return mUidMap.get(userId); 1098 } 1099 1100 public int size() { 1101 // total number of pending broadcast entries across all userIds 1102 int num = 0; 1103 for (int i = 0; i< mUidMap.size(); i++) { 1104 num += mUidMap.valueAt(i).size(); 1105 } 1106 return num; 1107 } 1108 1109 public void clear() { 1110 mUidMap.clear(); 1111 } 1112 1113 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1114 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1115 if (map == null) { 1116 map = new ArrayMap<String, ArrayList<String>>(); 1117 mUidMap.put(userId, map); 1118 } 1119 return map; 1120 } 1121 } 1122 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1123 1124 // Service Connection to remote media container service to copy 1125 // package uri's from external media onto secure containers 1126 // or internal storage. 1127 private IMediaContainerService mContainerService = null; 1128 1129 static final int SEND_PENDING_BROADCAST = 1; 1130 static final int MCS_BOUND = 3; 1131 static final int END_COPY = 4; 1132 static final int INIT_COPY = 5; 1133 static final int MCS_UNBIND = 6; 1134 static final int START_CLEANING_PACKAGE = 7; 1135 static final int FIND_INSTALL_LOC = 8; 1136 static final int POST_INSTALL = 9; 1137 static final int MCS_RECONNECT = 10; 1138 static final int MCS_GIVE_UP = 11; 1139 static final int UPDATED_MEDIA_STATUS = 12; 1140 static final int WRITE_SETTINGS = 13; 1141 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1142 static final int PACKAGE_VERIFIED = 15; 1143 static final int CHECK_PENDING_VERIFICATION = 16; 1144 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1145 static final int INTENT_FILTER_VERIFIED = 18; 1146 static final int WRITE_PACKAGE_LIST = 19; 1147 static final int EPHEMERAL_RESOLUTION_PHASE_TWO = 20; 1148 1149 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1150 1151 // Delay time in millisecs 1152 static final int BROADCAST_DELAY = 10 * 1000; 1153 1154 static UserManagerService sUserManager; 1155 1156 // Stores a list of users whose package restrictions file needs to be updated 1157 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1158 1159 final private DefaultContainerConnection mDefContainerConn = 1160 new DefaultContainerConnection(); 1161 class DefaultContainerConnection implements ServiceConnection { 1162 public void onServiceConnected(ComponentName name, IBinder service) { 1163 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1164 final IMediaContainerService imcs = IMediaContainerService.Stub 1165 .asInterface(Binder.allowBlocking(service)); 1166 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1167 } 1168 1169 public void onServiceDisconnected(ComponentName name) { 1170 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1171 } 1172 } 1173 1174 // Recordkeeping of restore-after-install operations that are currently in flight 1175 // between the Package Manager and the Backup Manager 1176 static class PostInstallData { 1177 public InstallArgs args; 1178 public PackageInstalledInfo res; 1179 1180 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1181 args = _a; 1182 res = _r; 1183 } 1184 } 1185 1186 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1187 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1188 1189 // XML tags for backup/restore of various bits of state 1190 private static final String TAG_PREFERRED_BACKUP = "pa"; 1191 private static final String TAG_DEFAULT_APPS = "da"; 1192 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1193 1194 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1195 private static final String TAG_ALL_GRANTS = "rt-grants"; 1196 private static final String TAG_GRANT = "grant"; 1197 private static final String ATTR_PACKAGE_NAME = "pkg"; 1198 1199 private static final String TAG_PERMISSION = "perm"; 1200 private static final String ATTR_PERMISSION_NAME = "name"; 1201 private static final String ATTR_IS_GRANTED = "g"; 1202 private static final String ATTR_USER_SET = "set"; 1203 private static final String ATTR_USER_FIXED = "fixed"; 1204 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1205 1206 // System/policy permission grants are not backed up 1207 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1208 FLAG_PERMISSION_POLICY_FIXED 1209 | FLAG_PERMISSION_SYSTEM_FIXED 1210 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1211 1212 // And we back up these user-adjusted states 1213 private static final int USER_RUNTIME_GRANT_MASK = 1214 FLAG_PERMISSION_USER_SET 1215 | FLAG_PERMISSION_USER_FIXED 1216 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1217 1218 final @Nullable String mRequiredVerifierPackage; 1219 final @NonNull String mRequiredInstallerPackage; 1220 final @NonNull String mRequiredUninstallerPackage; 1221 final @Nullable String mSetupWizardPackage; 1222 final @Nullable String mStorageManagerPackage; 1223 final @NonNull String mServicesSystemSharedLibraryPackageName; 1224 final @NonNull String mSharedSystemSharedLibraryPackageName; 1225 1226 final boolean mPermissionReviewRequired; 1227 1228 private final PackageUsage mPackageUsage = new PackageUsage(); 1229 private final CompilerStats mCompilerStats = new CompilerStats(); 1230 1231 class PackageHandler extends Handler { 1232 private boolean mBound = false; 1233 final ArrayList<HandlerParams> mPendingInstalls = 1234 new ArrayList<HandlerParams>(); 1235 1236 private boolean connectToService() { 1237 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1238 " DefaultContainerService"); 1239 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1240 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1241 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1242 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1243 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1244 mBound = true; 1245 return true; 1246 } 1247 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1248 return false; 1249 } 1250 1251 private void disconnectService() { 1252 mContainerService = null; 1253 mBound = false; 1254 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1255 mContext.unbindService(mDefContainerConn); 1256 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1257 } 1258 1259 PackageHandler(Looper looper) { 1260 super(looper); 1261 } 1262 1263 public void handleMessage(Message msg) { 1264 try { 1265 doHandleMessage(msg); 1266 } finally { 1267 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1268 } 1269 } 1270 1271 void doHandleMessage(Message msg) { 1272 switch (msg.what) { 1273 case INIT_COPY: { 1274 HandlerParams params = (HandlerParams) msg.obj; 1275 int idx = mPendingInstalls.size(); 1276 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1277 // If a bind was already initiated we dont really 1278 // need to do anything. The pending install 1279 // will be processed later on. 1280 if (!mBound) { 1281 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1282 System.identityHashCode(mHandler)); 1283 // If this is the only one pending we might 1284 // have to bind to the service again. 1285 if (!connectToService()) { 1286 Slog.e(TAG, "Failed to bind to media container service"); 1287 params.serviceError(); 1288 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1289 System.identityHashCode(mHandler)); 1290 if (params.traceMethod != null) { 1291 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1292 params.traceCookie); 1293 } 1294 return; 1295 } else { 1296 // Once we bind to the service, the first 1297 // pending request will be processed. 1298 mPendingInstalls.add(idx, params); 1299 } 1300 } else { 1301 mPendingInstalls.add(idx, params); 1302 // Already bound to the service. Just make 1303 // sure we trigger off processing the first request. 1304 if (idx == 0) { 1305 mHandler.sendEmptyMessage(MCS_BOUND); 1306 } 1307 } 1308 break; 1309 } 1310 case MCS_BOUND: { 1311 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1312 if (msg.obj != null) { 1313 mContainerService = (IMediaContainerService) msg.obj; 1314 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1315 System.identityHashCode(mHandler)); 1316 } 1317 if (mContainerService == null) { 1318 if (!mBound) { 1319 // Something seriously wrong since we are not bound and we are not 1320 // waiting for connection. Bail out. 1321 Slog.e(TAG, "Cannot bind to media container service"); 1322 for (HandlerParams params : mPendingInstalls) { 1323 // Indicate service bind error 1324 params.serviceError(); 1325 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1326 System.identityHashCode(params)); 1327 if (params.traceMethod != null) { 1328 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1329 params.traceMethod, params.traceCookie); 1330 } 1331 return; 1332 } 1333 mPendingInstalls.clear(); 1334 } else { 1335 Slog.w(TAG, "Waiting to connect to media container service"); 1336 } 1337 } else if (mPendingInstalls.size() > 0) { 1338 HandlerParams params = mPendingInstalls.get(0); 1339 if (params != null) { 1340 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1341 System.identityHashCode(params)); 1342 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1343 if (params.startCopy()) { 1344 // We are done... look for more work or to 1345 // go idle. 1346 if (DEBUG_SD_INSTALL) Log.i(TAG, 1347 "Checking for more work or unbind..."); 1348 // Delete pending install 1349 if (mPendingInstalls.size() > 0) { 1350 mPendingInstalls.remove(0); 1351 } 1352 if (mPendingInstalls.size() == 0) { 1353 if (mBound) { 1354 if (DEBUG_SD_INSTALL) Log.i(TAG, 1355 "Posting delayed MCS_UNBIND"); 1356 removeMessages(MCS_UNBIND); 1357 Message ubmsg = obtainMessage(MCS_UNBIND); 1358 // Unbind after a little delay, to avoid 1359 // continual thrashing. 1360 sendMessageDelayed(ubmsg, 10000); 1361 } 1362 } else { 1363 // There are more pending requests in queue. 1364 // Just post MCS_BOUND message to trigger processing 1365 // of next pending install. 1366 if (DEBUG_SD_INSTALL) Log.i(TAG, 1367 "Posting MCS_BOUND for next work"); 1368 mHandler.sendEmptyMessage(MCS_BOUND); 1369 } 1370 } 1371 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1372 } 1373 } else { 1374 // Should never happen ideally. 1375 Slog.w(TAG, "Empty queue"); 1376 } 1377 break; 1378 } 1379 case MCS_RECONNECT: { 1380 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1381 if (mPendingInstalls.size() > 0) { 1382 if (mBound) { 1383 disconnectService(); 1384 } 1385 if (!connectToService()) { 1386 Slog.e(TAG, "Failed to bind to media container service"); 1387 for (HandlerParams params : mPendingInstalls) { 1388 // Indicate service bind error 1389 params.serviceError(); 1390 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1391 System.identityHashCode(params)); 1392 } 1393 mPendingInstalls.clear(); 1394 } 1395 } 1396 break; 1397 } 1398 case MCS_UNBIND: { 1399 // If there is no actual work left, then time to unbind. 1400 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1401 1402 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1403 if (mBound) { 1404 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1405 1406 disconnectService(); 1407 } 1408 } else if (mPendingInstalls.size() > 0) { 1409 // There are more pending requests in queue. 1410 // Just post MCS_BOUND message to trigger processing 1411 // of next pending install. 1412 mHandler.sendEmptyMessage(MCS_BOUND); 1413 } 1414 1415 break; 1416 } 1417 case MCS_GIVE_UP: { 1418 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1419 HandlerParams params = mPendingInstalls.remove(0); 1420 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1421 System.identityHashCode(params)); 1422 break; 1423 } 1424 case SEND_PENDING_BROADCAST: { 1425 String packages[]; 1426 ArrayList<String> components[]; 1427 int size = 0; 1428 int uids[]; 1429 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1430 synchronized (mPackages) { 1431 if (mPendingBroadcasts == null) { 1432 return; 1433 } 1434 size = mPendingBroadcasts.size(); 1435 if (size <= 0) { 1436 // Nothing to be done. Just return 1437 return; 1438 } 1439 packages = new String[size]; 1440 components = new ArrayList[size]; 1441 uids = new int[size]; 1442 int i = 0; // filling out the above arrays 1443 1444 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1445 int packageUserId = mPendingBroadcasts.userIdAt(n); 1446 Iterator<Map.Entry<String, ArrayList<String>>> it 1447 = mPendingBroadcasts.packagesForUserId(packageUserId) 1448 .entrySet().iterator(); 1449 while (it.hasNext() && i < size) { 1450 Map.Entry<String, ArrayList<String>> ent = it.next(); 1451 packages[i] = ent.getKey(); 1452 components[i] = ent.getValue(); 1453 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1454 uids[i] = (ps != null) 1455 ? UserHandle.getUid(packageUserId, ps.appId) 1456 : -1; 1457 i++; 1458 } 1459 } 1460 size = i; 1461 mPendingBroadcasts.clear(); 1462 } 1463 // Send broadcasts 1464 for (int i = 0; i < size; i++) { 1465 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1466 } 1467 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1468 break; 1469 } 1470 case START_CLEANING_PACKAGE: { 1471 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1472 final String packageName = (String)msg.obj; 1473 final int userId = msg.arg1; 1474 final boolean andCode = msg.arg2 != 0; 1475 synchronized (mPackages) { 1476 if (userId == UserHandle.USER_ALL) { 1477 int[] users = sUserManager.getUserIds(); 1478 for (int user : users) { 1479 mSettings.addPackageToCleanLPw( 1480 new PackageCleanItem(user, packageName, andCode)); 1481 } 1482 } else { 1483 mSettings.addPackageToCleanLPw( 1484 new PackageCleanItem(userId, packageName, andCode)); 1485 } 1486 } 1487 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1488 startCleaningPackages(); 1489 } break; 1490 case POST_INSTALL: { 1491 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1492 1493 PostInstallData data = mRunningInstalls.get(msg.arg1); 1494 final boolean didRestore = (msg.arg2 != 0); 1495 mRunningInstalls.delete(msg.arg1); 1496 1497 if (data != null) { 1498 InstallArgs args = data.args; 1499 PackageInstalledInfo parentRes = data.res; 1500 1501 final boolean grantPermissions = (args.installFlags 1502 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1503 final boolean killApp = (args.installFlags 1504 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1505 final String[] grantedPermissions = args.installGrantPermissions; 1506 1507 // Handle the parent package 1508 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1509 grantedPermissions, didRestore, args.installerPackageName, 1510 args.observer); 1511 1512 // Handle the child packages 1513 final int childCount = (parentRes.addedChildPackages != null) 1514 ? parentRes.addedChildPackages.size() : 0; 1515 for (int i = 0; i < childCount; i++) { 1516 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1517 handlePackagePostInstall(childRes, grantPermissions, killApp, 1518 grantedPermissions, false, args.installerPackageName, 1519 args.observer); 1520 } 1521 1522 // Log tracing if needed 1523 if (args.traceMethod != null) { 1524 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1525 args.traceCookie); 1526 } 1527 } else { 1528 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1529 } 1530 1531 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1532 } break; 1533 case UPDATED_MEDIA_STATUS: { 1534 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1535 boolean reportStatus = msg.arg1 == 1; 1536 boolean doGc = msg.arg2 == 1; 1537 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1538 if (doGc) { 1539 // Force a gc to clear up stale containers. 1540 Runtime.getRuntime().gc(); 1541 } 1542 if (msg.obj != null) { 1543 @SuppressWarnings("unchecked") 1544 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1545 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1546 // Unload containers 1547 unloadAllContainers(args); 1548 } 1549 if (reportStatus) { 1550 try { 1551 if (DEBUG_SD_INSTALL) Log.i(TAG, 1552 "Invoking StorageManagerService call back"); 1553 PackageHelper.getStorageManager().finishMediaUpdate(); 1554 } catch (RemoteException e) { 1555 Log.e(TAG, "StorageManagerService not running?"); 1556 } 1557 } 1558 } break; 1559 case WRITE_SETTINGS: { 1560 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1561 synchronized (mPackages) { 1562 removeMessages(WRITE_SETTINGS); 1563 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1564 mSettings.writeLPr(); 1565 mDirtyUsers.clear(); 1566 } 1567 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1568 } break; 1569 case WRITE_PACKAGE_RESTRICTIONS: { 1570 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1571 synchronized (mPackages) { 1572 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1573 for (int userId : mDirtyUsers) { 1574 mSettings.writePackageRestrictionsLPr(userId); 1575 } 1576 mDirtyUsers.clear(); 1577 } 1578 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1579 } break; 1580 case WRITE_PACKAGE_LIST: { 1581 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1582 synchronized (mPackages) { 1583 removeMessages(WRITE_PACKAGE_LIST); 1584 mSettings.writePackageListLPr(msg.arg1); 1585 } 1586 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1587 } break; 1588 case CHECK_PENDING_VERIFICATION: { 1589 final int verificationId = msg.arg1; 1590 final PackageVerificationState state = mPendingVerification.get(verificationId); 1591 1592 if ((state != null) && !state.timeoutExtended()) { 1593 final InstallArgs args = state.getInstallArgs(); 1594 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1595 1596 Slog.i(TAG, "Verification timed out for " + originUri); 1597 mPendingVerification.remove(verificationId); 1598 1599 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1600 1601 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1602 Slog.i(TAG, "Continuing with installation of " + originUri); 1603 state.setVerifierResponse(Binder.getCallingUid(), 1604 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1605 broadcastPackageVerified(verificationId, originUri, 1606 PackageManager.VERIFICATION_ALLOW, 1607 state.getInstallArgs().getUser()); 1608 try { 1609 ret = args.copyApk(mContainerService, true); 1610 } catch (RemoteException e) { 1611 Slog.e(TAG, "Could not contact the ContainerService"); 1612 } 1613 } else { 1614 broadcastPackageVerified(verificationId, originUri, 1615 PackageManager.VERIFICATION_REJECT, 1616 state.getInstallArgs().getUser()); 1617 } 1618 1619 Trace.asyncTraceEnd( 1620 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1621 1622 processPendingInstall(args, ret); 1623 mHandler.sendEmptyMessage(MCS_UNBIND); 1624 } 1625 break; 1626 } 1627 case PACKAGE_VERIFIED: { 1628 final int verificationId = msg.arg1; 1629 1630 final PackageVerificationState state = mPendingVerification.get(verificationId); 1631 if (state == null) { 1632 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1633 break; 1634 } 1635 1636 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1637 1638 state.setVerifierResponse(response.callerUid, response.code); 1639 1640 if (state.isVerificationComplete()) { 1641 mPendingVerification.remove(verificationId); 1642 1643 final InstallArgs args = state.getInstallArgs(); 1644 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1645 1646 int ret; 1647 if (state.isInstallAllowed()) { 1648 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1649 broadcastPackageVerified(verificationId, originUri, 1650 response.code, state.getInstallArgs().getUser()); 1651 try { 1652 ret = args.copyApk(mContainerService, true); 1653 } catch (RemoteException e) { 1654 Slog.e(TAG, "Could not contact the ContainerService"); 1655 } 1656 } else { 1657 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1658 } 1659 1660 Trace.asyncTraceEnd( 1661 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1662 1663 processPendingInstall(args, ret); 1664 mHandler.sendEmptyMessage(MCS_UNBIND); 1665 } 1666 1667 break; 1668 } 1669 case START_INTENT_FILTER_VERIFICATIONS: { 1670 IFVerificationParams params = (IFVerificationParams) msg.obj; 1671 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1672 params.replacing, params.pkg); 1673 break; 1674 } 1675 case INTENT_FILTER_VERIFIED: { 1676 final int verificationId = msg.arg1; 1677 1678 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1679 verificationId); 1680 if (state == null) { 1681 Slog.w(TAG, "Invalid IntentFilter verification token " 1682 + verificationId + " received"); 1683 break; 1684 } 1685 1686 final int userId = state.getUserId(); 1687 1688 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1689 "Processing IntentFilter verification with token:" 1690 + verificationId + " and userId:" + userId); 1691 1692 final IntentFilterVerificationResponse response = 1693 (IntentFilterVerificationResponse) msg.obj; 1694 1695 state.setVerifierResponse(response.callerUid, response.code); 1696 1697 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1698 "IntentFilter verification with token:" + verificationId 1699 + " and userId:" + userId 1700 + " is settings verifier response with response code:" 1701 + response.code); 1702 1703 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1704 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1705 + response.getFailedDomainsString()); 1706 } 1707 1708 if (state.isVerificationComplete()) { 1709 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1710 } else { 1711 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1712 "IntentFilter verification with token:" + verificationId 1713 + " was not said to be complete"); 1714 } 1715 1716 break; 1717 } 1718 case EPHEMERAL_RESOLUTION_PHASE_TWO: { 1719 EphemeralResolver.doEphemeralResolutionPhaseTwo(mContext, 1720 mEphemeralResolverConnection, 1721 (EphemeralRequest) msg.obj, 1722 mEphemeralInstallerActivity, 1723 mHandler); 1724 } 1725 } 1726 } 1727 } 1728 1729 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1730 boolean killApp, String[] grantedPermissions, 1731 boolean launchedForRestore, String installerPackage, 1732 IPackageInstallObserver2 installObserver) { 1733 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1734 // Send the removed broadcasts 1735 if (res.removedInfo != null) { 1736 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1737 } 1738 1739 // Now that we successfully installed the package, grant runtime 1740 // permissions if requested before broadcasting the install. Also 1741 // for legacy apps in permission review mode we clear the permission 1742 // review flag which is used to emulate runtime permissions for 1743 // legacy apps. 1744 if (grantPermissions) { 1745 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1746 } 1747 1748 final boolean update = res.removedInfo != null 1749 && res.removedInfo.removedPackage != null; 1750 1751 // If this is the first time we have child packages for a disabled privileged 1752 // app that had no children, we grant requested runtime permissions to the new 1753 // children if the parent on the system image had them already granted. 1754 if (res.pkg.parentPackage != null) { 1755 synchronized (mPackages) { 1756 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1757 } 1758 } 1759 1760 synchronized (mPackages) { 1761 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers); 1762 } 1763 1764 final String packageName = res.pkg.applicationInfo.packageName; 1765 1766 // Determine the set of users who are adding this package for 1767 // the first time vs. those who are seeing an update. 1768 int[] firstUsers = EMPTY_INT_ARRAY; 1769 int[] updateUsers = EMPTY_INT_ARRAY; 1770 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0; 1771 final PackageSetting ps = (PackageSetting) res.pkg.mExtras; 1772 for (int newUser : res.newUsers) { 1773 if (ps.getInstantApp(newUser)) { 1774 continue; 1775 } 1776 if (allNewUsers) { 1777 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1778 continue; 1779 } 1780 boolean isNew = true; 1781 for (int origUser : res.origUsers) { 1782 if (origUser == newUser) { 1783 isNew = false; 1784 break; 1785 } 1786 } 1787 if (isNew) { 1788 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1789 } else { 1790 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1791 } 1792 } 1793 1794 // Send installed broadcasts if the package is not a static shared lib. 1795 if (res.pkg.staticSharedLibName == null) { 1796 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1797 1798 // Send added for users that see the package for the first time 1799 // sendPackageAddedForNewUsers also deals with system apps 1800 int appId = UserHandle.getAppId(res.uid); 1801 boolean isSystem = res.pkg.applicationInfo.isSystemApp(); 1802 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers); 1803 1804 // Send added for users that don't see the package for the first time 1805 Bundle extras = new Bundle(1); 1806 extras.putInt(Intent.EXTRA_UID, res.uid); 1807 if (update) { 1808 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1809 } 1810 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1811 extras, 0 /*flags*/, null /*targetPackage*/, 1812 null /*finishedReceiver*/, updateUsers); 1813 1814 // Send replaced for users that don't see the package for the first time 1815 if (update) { 1816 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1817 packageName, extras, 0 /*flags*/, 1818 null /*targetPackage*/, null /*finishedReceiver*/, 1819 updateUsers); 1820 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1821 null /*package*/, null /*extras*/, 0 /*flags*/, 1822 packageName /*targetPackage*/, 1823 null /*finishedReceiver*/, updateUsers); 1824 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1825 // First-install and we did a restore, so we're responsible for the 1826 // first-launch broadcast. 1827 if (DEBUG_BACKUP) { 1828 Slog.i(TAG, "Post-restore of " + packageName 1829 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1830 } 1831 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1832 } 1833 1834 // Send broadcast package appeared if forward locked/external for all users 1835 // treat asec-hosted packages like removable media on upgrade 1836 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1837 if (DEBUG_INSTALL) { 1838 Slog.i(TAG, "upgrading pkg " + res.pkg 1839 + " is ASEC-hosted -> AVAILABLE"); 1840 } 1841 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1842 ArrayList<String> pkgList = new ArrayList<>(1); 1843 pkgList.add(packageName); 1844 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1845 } 1846 } 1847 1848 // Work that needs to happen on first install within each user 1849 if (firstUsers != null && firstUsers.length > 0) { 1850 synchronized (mPackages) { 1851 for (int userId : firstUsers) { 1852 // If this app is a browser and it's newly-installed for some 1853 // users, clear any default-browser state in those users. The 1854 // app's nature doesn't depend on the user, so we can just check 1855 // its browser nature in any user and generalize. 1856 if (packageIsBrowser(packageName, userId)) { 1857 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1858 } 1859 1860 // We may also need to apply pending (restored) runtime 1861 // permission grants within these users. 1862 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1863 } 1864 } 1865 } 1866 1867 // Log current value of "unknown sources" setting 1868 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1869 getUnknownSourcesSettings()); 1870 1871 // Force a gc to clear up things 1872 Runtime.getRuntime().gc(); 1873 1874 // Remove the replaced package's older resources safely now 1875 // We delete after a gc for applications on sdcard. 1876 if (res.removedInfo != null && res.removedInfo.args != null) { 1877 synchronized (mInstallLock) { 1878 res.removedInfo.args.doPostDeleteLI(true); 1879 } 1880 } 1881 1882 // Notify DexManager that the package was installed for new users. 1883 // The updated users should already be indexed and the package code paths 1884 // should not change. 1885 // Don't notify the manager for ephemeral apps as they are not expected to 1886 // survive long enough to benefit of background optimizations. 1887 for (int userId : firstUsers) { 1888 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId); 1889 mDexManager.notifyPackageInstalled(info, userId); 1890 } 1891 } 1892 1893 // If someone is watching installs - notify them 1894 if (installObserver != null) { 1895 try { 1896 Bundle extras = extrasForInstallResult(res); 1897 installObserver.onPackageInstalled(res.name, res.returnCode, 1898 res.returnMsg, extras); 1899 } catch (RemoteException e) { 1900 Slog.i(TAG, "Observer no longer exists."); 1901 } 1902 } 1903 } 1904 1905 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1906 PackageParser.Package pkg) { 1907 if (pkg.parentPackage == null) { 1908 return; 1909 } 1910 if (pkg.requestedPermissions == null) { 1911 return; 1912 } 1913 final PackageSetting disabledSysParentPs = mSettings 1914 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1915 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1916 || !disabledSysParentPs.isPrivileged() 1917 || (disabledSysParentPs.childPackageNames != null 1918 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1919 return; 1920 } 1921 final int[] allUserIds = sUserManager.getUserIds(); 1922 final int permCount = pkg.requestedPermissions.size(); 1923 for (int i = 0; i < permCount; i++) { 1924 String permission = pkg.requestedPermissions.get(i); 1925 BasePermission bp = mSettings.mPermissions.get(permission); 1926 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1927 continue; 1928 } 1929 for (int userId : allUserIds) { 1930 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1931 permission, userId)) { 1932 grantRuntimePermission(pkg.packageName, permission, userId); 1933 } 1934 } 1935 } 1936 } 1937 1938 private StorageEventListener mStorageListener = new StorageEventListener() { 1939 @Override 1940 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1941 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1942 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1943 final String volumeUuid = vol.getFsUuid(); 1944 1945 // Clean up any users or apps that were removed or recreated 1946 // while this volume was missing 1947 sUserManager.reconcileUsers(volumeUuid); 1948 reconcileApps(volumeUuid); 1949 1950 // Clean up any install sessions that expired or were 1951 // cancelled while this volume was missing 1952 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1953 1954 loadPrivatePackages(vol); 1955 1956 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1957 unloadPrivatePackages(vol); 1958 } 1959 } 1960 1961 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1962 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1963 updateExternalMediaStatus(true, false); 1964 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1965 updateExternalMediaStatus(false, false); 1966 } 1967 } 1968 } 1969 1970 @Override 1971 public void onVolumeForgotten(String fsUuid) { 1972 if (TextUtils.isEmpty(fsUuid)) { 1973 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1974 return; 1975 } 1976 1977 // Remove any apps installed on the forgotten volume 1978 synchronized (mPackages) { 1979 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1980 for (PackageSetting ps : packages) { 1981 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1982 deletePackageVersioned(new VersionedPackage(ps.name, 1983 PackageManager.VERSION_CODE_HIGHEST), 1984 new LegacyPackageDeleteObserver(null).getBinder(), 1985 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1986 // Try very hard to release any references to this package 1987 // so we don't risk the system server being killed due to 1988 // open FDs 1989 AttributeCache.instance().removePackage(ps.name); 1990 } 1991 1992 mSettings.onVolumeForgotten(fsUuid); 1993 mSettings.writeLPr(); 1994 } 1995 } 1996 }; 1997 1998 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1999 String[] grantedPermissions) { 2000 for (int userId : userIds) { 2001 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 2002 } 2003 } 2004 2005 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 2006 String[] grantedPermissions) { 2007 SettingBase sb = (SettingBase) pkg.mExtras; 2008 if (sb == null) { 2009 return; 2010 } 2011 2012 PermissionsState permissionsState = sb.getPermissionsState(); 2013 2014 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 2015 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 2016 2017 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 2018 >= Build.VERSION_CODES.M; 2019 2020 for (String permission : pkg.requestedPermissions) { 2021 final BasePermission bp; 2022 synchronized (mPackages) { 2023 bp = mSettings.mPermissions.get(permission); 2024 } 2025 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 2026 && (grantedPermissions == null 2027 || ArrayUtils.contains(grantedPermissions, permission))) { 2028 final int flags = permissionsState.getPermissionFlags(permission, userId); 2029 if (supportsRuntimePermissions) { 2030 // Installer cannot change immutable permissions. 2031 if ((flags & immutableFlags) == 0) { 2032 grantRuntimePermission(pkg.packageName, permission, userId); 2033 } 2034 } else if (mPermissionReviewRequired) { 2035 // In permission review mode we clear the review flag when we 2036 // are asked to install the app with all permissions granted. 2037 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 2038 updatePermissionFlags(permission, pkg.packageName, 2039 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId); 2040 } 2041 } 2042 } 2043 } 2044 } 2045 2046 Bundle extrasForInstallResult(PackageInstalledInfo res) { 2047 Bundle extras = null; 2048 switch (res.returnCode) { 2049 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 2050 extras = new Bundle(); 2051 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 2052 res.origPermission); 2053 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 2054 res.origPackage); 2055 break; 2056 } 2057 case PackageManager.INSTALL_SUCCEEDED: { 2058 extras = new Bundle(); 2059 extras.putBoolean(Intent.EXTRA_REPLACING, 2060 res.removedInfo != null && res.removedInfo.removedPackage != null); 2061 break; 2062 } 2063 } 2064 return extras; 2065 } 2066 2067 void scheduleWriteSettingsLocked() { 2068 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 2069 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 2070 } 2071 } 2072 2073 void scheduleWritePackageListLocked(int userId) { 2074 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 2075 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 2076 msg.arg1 = userId; 2077 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 2078 } 2079 } 2080 2081 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 2082 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 2083 scheduleWritePackageRestrictionsLocked(userId); 2084 } 2085 2086 void scheduleWritePackageRestrictionsLocked(int userId) { 2087 final int[] userIds = (userId == UserHandle.USER_ALL) 2088 ? sUserManager.getUserIds() : new int[]{userId}; 2089 for (int nextUserId : userIds) { 2090 if (!sUserManager.exists(nextUserId)) return; 2091 mDirtyUsers.add(nextUserId); 2092 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 2093 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 2094 } 2095 } 2096 } 2097 2098 public static PackageManagerService main(Context context, Installer installer, 2099 boolean factoryTest, boolean onlyCore) { 2100 // Self-check for initial settings. 2101 PackageManagerServiceCompilerMapping.checkProperties(); 2102 2103 PackageManagerService m = new PackageManagerService(context, installer, 2104 factoryTest, onlyCore); 2105 m.enableSystemUserPackages(); 2106 ServiceManager.addService("package", m); 2107 return m; 2108 } 2109 2110 private void enableSystemUserPackages() { 2111 if (!UserManager.isSplitSystemUser()) { 2112 return; 2113 } 2114 // For system user, enable apps based on the following conditions: 2115 // - app is whitelisted or belong to one of these groups: 2116 // -- system app which has no launcher icons 2117 // -- system app which has INTERACT_ACROSS_USERS permission 2118 // -- system IME app 2119 // - app is not in the blacklist 2120 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 2121 Set<String> enableApps = new ArraySet<>(); 2122 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 2123 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 2124 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 2125 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2126 enableApps.addAll(wlApps); 2127 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2128 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2129 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2130 enableApps.removeAll(blApps); 2131 Log.i(TAG, "Applications installed for system user: " + enableApps); 2132 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2133 UserHandle.SYSTEM); 2134 final int allAppsSize = allAps.size(); 2135 synchronized (mPackages) { 2136 for (int i = 0; i < allAppsSize; i++) { 2137 String pName = allAps.get(i); 2138 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2139 // Should not happen, but we shouldn't be failing if it does 2140 if (pkgSetting == null) { 2141 continue; 2142 } 2143 boolean install = enableApps.contains(pName); 2144 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2145 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2146 + " for system user"); 2147 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2148 } 2149 } 2150 } 2151 } 2152 2153 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2154 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2155 Context.DISPLAY_SERVICE); 2156 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2157 } 2158 2159 /** 2160 * Requests that files preopted on a secondary system partition be copied to the data partition 2161 * if possible. Note that the actual copying of the files is accomplished by init for security 2162 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2163 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2164 */ 2165 private static void requestCopyPreoptedFiles() { 2166 final int WAIT_TIME_MS = 100; 2167 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2168 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2169 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2170 // We will wait for up to 100 seconds. 2171 final long timeStart = SystemClock.uptimeMillis(); 2172 final long timeEnd = timeStart + 100 * 1000; 2173 long timeNow = timeStart; 2174 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2175 try { 2176 Thread.sleep(WAIT_TIME_MS); 2177 } catch (InterruptedException e) { 2178 // Do nothing 2179 } 2180 timeNow = SystemClock.uptimeMillis(); 2181 if (timeNow > timeEnd) { 2182 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2183 Slog.wtf(TAG, "cppreopt did not finish!"); 2184 break; 2185 } 2186 } 2187 2188 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms"); 2189 } 2190 } 2191 2192 public PackageManagerService(Context context, Installer installer, 2193 boolean factoryTest, boolean onlyCore) { 2194 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager"); 2195 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2196 SystemClock.uptimeMillis()); 2197 2198 if (mSdkVersion <= 0) { 2199 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2200 } 2201 2202 mContext = context; 2203 2204 mPermissionReviewRequired = context.getResources().getBoolean( 2205 R.bool.config_permissionReviewRequired); 2206 2207 mFactoryTest = factoryTest; 2208 mOnlyCore = onlyCore; 2209 mMetrics = new DisplayMetrics(); 2210 mSettings = new Settings(mPackages); 2211 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2212 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2213 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2214 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2215 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2216 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2217 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2218 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2219 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2220 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2221 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2222 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2223 2224 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2225 if (separateProcesses != null && separateProcesses.length() > 0) { 2226 if ("*".equals(separateProcesses)) { 2227 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2228 mSeparateProcesses = null; 2229 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2230 } else { 2231 mDefParseFlags = 0; 2232 mSeparateProcesses = separateProcesses.split(","); 2233 Slog.w(TAG, "Running with debug.separate_processes: " 2234 + separateProcesses); 2235 } 2236 } else { 2237 mDefParseFlags = 0; 2238 mSeparateProcesses = null; 2239 } 2240 2241 mInstaller = installer; 2242 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2243 "*dexopt*"); 2244 mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock); 2245 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2246 2247 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2248 FgThread.get().getLooper()); 2249 2250 getDefaultDisplayMetrics(context, mMetrics); 2251 2252 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config"); 2253 SystemConfig systemConfig = SystemConfig.getInstance(); 2254 mGlobalGids = systemConfig.getGlobalGids(); 2255 mSystemPermissions = systemConfig.getSystemPermissions(); 2256 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2257 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2258 2259 mProtectedPackages = new ProtectedPackages(mContext); 2260 2261 synchronized (mInstallLock) { 2262 // writer 2263 synchronized (mPackages) { 2264 mHandlerThread = new ServiceThread(TAG, 2265 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2266 mHandlerThread.start(); 2267 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2268 mProcessLoggingHandler = new ProcessLoggingHandler(); 2269 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2270 2271 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 2272 mInstantAppRegistry = new InstantAppRegistry(this); 2273 2274 File dataDir = Environment.getDataDirectory(); 2275 mAppInstallDir = new File(dataDir, "app"); 2276 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2277 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2278 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2279 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2280 sUserManager = new UserManagerService(context, this, 2281 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages); 2282 2283 // Propagate permission configuration in to package manager. 2284 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2285 = systemConfig.getPermissions(); 2286 for (int i=0; i<permConfig.size(); i++) { 2287 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2288 BasePermission bp = mSettings.mPermissions.get(perm.name); 2289 if (bp == null) { 2290 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2291 mSettings.mPermissions.put(perm.name, bp); 2292 } 2293 if (perm.gids != null) { 2294 bp.setGids(perm.gids, perm.perUser); 2295 } 2296 } 2297 2298 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2299 final int builtInLibCount = libConfig.size(); 2300 for (int i = 0; i < builtInLibCount; i++) { 2301 String name = libConfig.keyAt(i); 2302 String path = libConfig.valueAt(i); 2303 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED, 2304 SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0); 2305 } 2306 2307 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2308 2309 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings"); 2310 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2311 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2312 2313 // Clean up orphaned packages for which the code path doesn't exist 2314 // and they are an update to a system app - caused by bug/32321269 2315 final int packageSettingCount = mSettings.mPackages.size(); 2316 for (int i = packageSettingCount - 1; i >= 0; i--) { 2317 PackageSetting ps = mSettings.mPackages.valueAt(i); 2318 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists()) 2319 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) { 2320 mSettings.mPackages.removeAt(i); 2321 mSettings.enableSystemPackageLPw(ps.name); 2322 } 2323 } 2324 2325 if (mFirstBoot) { 2326 requestCopyPreoptedFiles(); 2327 } 2328 2329 String customResolverActivity = Resources.getSystem().getString( 2330 R.string.config_customResolverActivity); 2331 if (TextUtils.isEmpty(customResolverActivity)) { 2332 customResolverActivity = null; 2333 } else { 2334 mCustomResolverComponentName = ComponentName.unflattenFromString( 2335 customResolverActivity); 2336 } 2337 2338 long startTime = SystemClock.uptimeMillis(); 2339 2340 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2341 startTime); 2342 2343 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2344 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2345 2346 if (bootClassPath == null) { 2347 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2348 } 2349 2350 if (systemServerClassPath == null) { 2351 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2352 } 2353 2354 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2355 final String[] dexCodeInstructionSets = 2356 getDexCodeInstructionSets( 2357 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2358 2359 /** 2360 * Ensure all external libraries have had dexopt run on them. 2361 */ 2362 if (mSharedLibraries.size() > 0) { 2363 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 2364 // NOTE: For now, we're compiling these system "shared libraries" 2365 // (and framework jars) into all available architectures. It's possible 2366 // to compile them only when we come across an app that uses them (there's 2367 // already logic for that in scanPackageLI) but that adds some complexity. 2368 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2369 final int libCount = mSharedLibraries.size(); 2370 for (int i = 0; i < libCount; i++) { 2371 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 2372 final int versionCount = versionedLib.size(); 2373 for (int j = 0; j < versionCount; j++) { 2374 SharedLibraryEntry libEntry = versionedLib.valueAt(j); 2375 final String libPath = libEntry.path != null 2376 ? libEntry.path : libEntry.apk; 2377 if (libPath == null) { 2378 continue; 2379 } 2380 try { 2381 // Shared libraries do not have profiles so we perform a full 2382 // AOT compilation (if needed). 2383 int dexoptNeeded = DexFile.getDexOptNeeded( 2384 libPath, dexCodeInstructionSet, 2385 getCompilerFilterForReason(REASON_SHARED_APK), 2386 false /* newProfile */); 2387 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2388 mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*", 2389 dexCodeInstructionSet, dexoptNeeded, null, 2390 DEXOPT_PUBLIC, 2391 getCompilerFilterForReason(REASON_SHARED_APK), 2392 StorageManager.UUID_PRIVATE_INTERNAL, 2393 SKIP_SHARED_LIBRARY_CHECK); 2394 } 2395 } catch (FileNotFoundException e) { 2396 Slog.w(TAG, "Library not found: " + libPath); 2397 } catch (IOException | InstallerException e) { 2398 Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? " 2399 + e.getMessage()); 2400 } 2401 } 2402 } 2403 } 2404 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2405 } 2406 2407 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2408 2409 final VersionInfo ver = mSettings.getInternalVersion(); 2410 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2411 2412 // when upgrading from pre-M, promote system app permissions from install to runtime 2413 mPromoteSystemApps = 2414 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2415 2416 // When upgrading from pre-N, we need to handle package extraction like first boot, 2417 // as there is no profiling data available. 2418 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2419 2420 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1; 2421 2422 // save off the names of pre-existing system packages prior to scanning; we don't 2423 // want to automatically grant runtime permissions for new system apps 2424 if (mPromoteSystemApps) { 2425 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2426 while (pkgSettingIter.hasNext()) { 2427 PackageSetting ps = pkgSettingIter.next(); 2428 if (isSystemApp(ps)) { 2429 mExistingSystemPackages.add(ps.name); 2430 } 2431 } 2432 } 2433 2434 mCacheDir = preparePackageParserCache(mIsUpgrade); 2435 2436 // Set flag to monitor and not change apk file paths when 2437 // scanning install directories. 2438 int scanFlags = SCAN_BOOTING | SCAN_INITIAL; 2439 2440 if (mIsUpgrade || mFirstBoot) { 2441 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE; 2442 } 2443 2444 // Collect vendor overlay packages. (Do this before scanning any apps.) 2445 // For security and version matching reason, only consider 2446 // overlay packages if they reside in the right directory. 2447 String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PERSIST_PROPERTY); 2448 if (overlayThemeDir.isEmpty()) { 2449 overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY); 2450 } 2451 if (!overlayThemeDir.isEmpty()) { 2452 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags 2453 | PackageParser.PARSE_IS_SYSTEM 2454 | PackageParser.PARSE_IS_SYSTEM_DIR 2455 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2456 } 2457 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags 2458 | PackageParser.PARSE_IS_SYSTEM 2459 | PackageParser.PARSE_IS_SYSTEM_DIR 2460 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2461 2462 // Find base frameworks (resource packages without code). 2463 scanDirTracedLI(frameworkDir, mDefParseFlags 2464 | PackageParser.PARSE_IS_SYSTEM 2465 | PackageParser.PARSE_IS_SYSTEM_DIR 2466 | PackageParser.PARSE_IS_PRIVILEGED, 2467 scanFlags | SCAN_NO_DEX, 0); 2468 2469 // Collected privileged system packages. 2470 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2471 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2472 | PackageParser.PARSE_IS_SYSTEM 2473 | PackageParser.PARSE_IS_SYSTEM_DIR 2474 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2475 2476 // Collect ordinary system packages. 2477 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2478 scanDirTracedLI(systemAppDir, mDefParseFlags 2479 | PackageParser.PARSE_IS_SYSTEM 2480 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2481 2482 // Collect all vendor packages. 2483 File vendorAppDir = new File("/vendor/app"); 2484 try { 2485 vendorAppDir = vendorAppDir.getCanonicalFile(); 2486 } catch (IOException e) { 2487 // failed to look up canonical path, continue with original one 2488 } 2489 scanDirTracedLI(vendorAppDir, mDefParseFlags 2490 | PackageParser.PARSE_IS_SYSTEM 2491 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2492 2493 // Collect all OEM packages. 2494 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2495 scanDirTracedLI(oemAppDir, mDefParseFlags 2496 | PackageParser.PARSE_IS_SYSTEM 2497 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2498 2499 // Prune any system packages that no longer exist. 2500 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2501 if (!mOnlyCore) { 2502 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2503 while (psit.hasNext()) { 2504 PackageSetting ps = psit.next(); 2505 2506 /* 2507 * If this is not a system app, it can't be a 2508 * disable system app. 2509 */ 2510 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2511 continue; 2512 } 2513 2514 /* 2515 * If the package is scanned, it's not erased. 2516 */ 2517 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2518 if (scannedPkg != null) { 2519 /* 2520 * If the system app is both scanned and in the 2521 * disabled packages list, then it must have been 2522 * added via OTA. Remove it from the currently 2523 * scanned package so the previously user-installed 2524 * application can be scanned. 2525 */ 2526 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2527 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2528 + ps.name + "; removing system app. Last known codePath=" 2529 + ps.codePathString + ", installStatus=" + ps.installStatus 2530 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2531 + scannedPkg.mVersionCode); 2532 removePackageLI(scannedPkg, true); 2533 mExpectingBetter.put(ps.name, ps.codePath); 2534 } 2535 2536 continue; 2537 } 2538 2539 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2540 psit.remove(); 2541 logCriticalInfo(Log.WARN, "System package " + ps.name 2542 + " no longer exists; it's data will be wiped"); 2543 // Actual deletion of code and data will be handled by later 2544 // reconciliation step 2545 } else { 2546 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2547 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2548 possiblyDeletedUpdatedSystemApps.add(ps.name); 2549 } 2550 } 2551 } 2552 } 2553 2554 //look for any incomplete package installations 2555 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2556 for (int i = 0; i < deletePkgsList.size(); i++) { 2557 // Actual deletion of code and data will be handled by later 2558 // reconciliation step 2559 final String packageName = deletePkgsList.get(i).name; 2560 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2561 synchronized (mPackages) { 2562 mSettings.removePackageLPw(packageName); 2563 } 2564 } 2565 2566 //delete tmp files 2567 deleteTempPackageFiles(); 2568 2569 // Remove any shared userIDs that have no associated packages 2570 mSettings.pruneSharedUsersLPw(); 2571 2572 if (!mOnlyCore) { 2573 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2574 SystemClock.uptimeMillis()); 2575 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2576 2577 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2578 | PackageParser.PARSE_FORWARD_LOCK, 2579 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2580 2581 scanDirLI(mEphemeralInstallDir, mDefParseFlags 2582 | PackageParser.PARSE_IS_EPHEMERAL, 2583 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2584 2585 /** 2586 * Remove disable package settings for any updated system 2587 * apps that were removed via an OTA. If they're not a 2588 * previously-updated app, remove them completely. 2589 * Otherwise, just revoke their system-level permissions. 2590 */ 2591 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2592 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2593 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2594 2595 String msg; 2596 if (deletedPkg == null) { 2597 msg = "Updated system package " + deletedAppName 2598 + " no longer exists; it's data will be wiped"; 2599 // Actual deletion of code and data will be handled by later 2600 // reconciliation step 2601 } else { 2602 msg = "Updated system app + " + deletedAppName 2603 + " no longer present; removing system privileges for " 2604 + deletedAppName; 2605 2606 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2607 2608 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2609 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2610 } 2611 logCriticalInfo(Log.WARN, msg); 2612 } 2613 2614 /** 2615 * Make sure all system apps that we expected to appear on 2616 * the userdata partition actually showed up. If they never 2617 * appeared, crawl back and revive the system version. 2618 */ 2619 for (int i = 0; i < mExpectingBetter.size(); i++) { 2620 final String packageName = mExpectingBetter.keyAt(i); 2621 if (!mPackages.containsKey(packageName)) { 2622 final File scanFile = mExpectingBetter.valueAt(i); 2623 2624 logCriticalInfo(Log.WARN, "Expected better " + packageName 2625 + " but never showed up; reverting to system"); 2626 2627 int reparseFlags = mDefParseFlags; 2628 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2629 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2630 | PackageParser.PARSE_IS_SYSTEM_DIR 2631 | PackageParser.PARSE_IS_PRIVILEGED; 2632 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2633 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2634 | PackageParser.PARSE_IS_SYSTEM_DIR; 2635 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2636 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2637 | PackageParser.PARSE_IS_SYSTEM_DIR; 2638 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2639 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2640 | PackageParser.PARSE_IS_SYSTEM_DIR; 2641 } else { 2642 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2643 continue; 2644 } 2645 2646 mSettings.enableSystemPackageLPw(packageName); 2647 2648 try { 2649 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2650 } catch (PackageManagerException e) { 2651 Slog.e(TAG, "Failed to parse original system package: " 2652 + e.getMessage()); 2653 } 2654 } 2655 } 2656 } 2657 mExpectingBetter.clear(); 2658 2659 // Resolve the storage manager. 2660 mStorageManagerPackage = getStorageManagerPackageName(); 2661 2662 // Resolve protected action filters. Only the setup wizard is allowed to 2663 // have a high priority filter for these actions. 2664 mSetupWizardPackage = getSetupWizardPackageName(); 2665 if (mProtectedFilters.size() > 0) { 2666 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2667 Slog.i(TAG, "No setup wizard;" 2668 + " All protected intents capped to priority 0"); 2669 } 2670 for (ActivityIntentInfo filter : mProtectedFilters) { 2671 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2672 if (DEBUG_FILTERS) { 2673 Slog.i(TAG, "Found setup wizard;" 2674 + " allow priority " + filter.getPriority() + ";" 2675 + " package: " + filter.activity.info.packageName 2676 + " activity: " + filter.activity.className 2677 + " priority: " + filter.getPriority()); 2678 } 2679 // skip setup wizard; allow it to keep the high priority filter 2680 continue; 2681 } 2682 Slog.w(TAG, "Protected action; cap priority to 0;" 2683 + " package: " + filter.activity.info.packageName 2684 + " activity: " + filter.activity.className 2685 + " origPrio: " + filter.getPriority()); 2686 filter.setPriority(0); 2687 } 2688 } 2689 mDeferProtectedFilters = false; 2690 mProtectedFilters.clear(); 2691 2692 // Now that we know all of the shared libraries, update all clients to have 2693 // the correct library paths. 2694 updateAllSharedLibrariesLPw(null); 2695 2696 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2697 // NOTE: We ignore potential failures here during a system scan (like 2698 // the rest of the commands above) because there's precious little we 2699 // can do about it. A settings error is reported, though. 2700 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/); 2701 } 2702 2703 // Now that we know all the packages we are keeping, 2704 // read and update their last usage times. 2705 mPackageUsage.read(mPackages); 2706 mCompilerStats.read(); 2707 2708 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2709 SystemClock.uptimeMillis()); 2710 Slog.i(TAG, "Time to scan packages: " 2711 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2712 + " seconds"); 2713 2714 // If the platform SDK has changed since the last time we booted, 2715 // we need to re-grant app permission to catch any new ones that 2716 // appear. This is really a hack, and means that apps can in some 2717 // cases get permissions that the user didn't initially explicitly 2718 // allow... it would be nice to have some better way to handle 2719 // this situation. 2720 int updateFlags = UPDATE_PERMISSIONS_ALL; 2721 if (ver.sdkVersion != mSdkVersion) { 2722 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2723 + mSdkVersion + "; regranting permissions for internal storage"); 2724 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2725 } 2726 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2727 ver.sdkVersion = mSdkVersion; 2728 2729 // If this is the first boot or an update from pre-M, and it is a normal 2730 // boot, then we need to initialize the default preferred apps across 2731 // all defined users. 2732 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2733 for (UserInfo user : sUserManager.getUsers(true)) { 2734 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2735 applyFactoryDefaultBrowserLPw(user.id); 2736 primeDomainVerificationsLPw(user.id); 2737 } 2738 } 2739 2740 // Prepare storage for system user really early during boot, 2741 // since core system apps like SettingsProvider and SystemUI 2742 // can't wait for user to start 2743 final int storageFlags; 2744 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2745 storageFlags = StorageManager.FLAG_STORAGE_DE; 2746 } else { 2747 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2748 } 2749 reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2750 storageFlags, true /* migrateAppData */); 2751 2752 // If this is first boot after an OTA, and a normal boot, then 2753 // we need to clear code cache directories. 2754 // Note that we do *not* clear the application profiles. These remain valid 2755 // across OTAs and are used to drive profile verification (post OTA) and 2756 // profile compilation (without waiting to collect a fresh set of profiles). 2757 if (mIsUpgrade && !onlyCore) { 2758 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2759 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2760 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2761 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2762 // No apps are running this early, so no need to freeze 2763 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2764 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2765 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2766 } 2767 } 2768 ver.fingerprint = Build.FINGERPRINT; 2769 } 2770 2771 checkDefaultBrowser(); 2772 2773 // clear only after permissions and other defaults have been updated 2774 mExistingSystemPackages.clear(); 2775 mPromoteSystemApps = false; 2776 2777 // All the changes are done during package scanning. 2778 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2779 2780 // can downgrade to reader 2781 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings"); 2782 mSettings.writeLPr(); 2783 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2784 2785 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2786 // early on (before the package manager declares itself as early) because other 2787 // components in the system server might ask for package contexts for these apps. 2788 // 2789 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2790 // (i.e, that the data partition is unavailable). 2791 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2792 long start = System.nanoTime(); 2793 List<PackageParser.Package> coreApps = new ArrayList<>(); 2794 for (PackageParser.Package pkg : mPackages.values()) { 2795 if (pkg.coreApp) { 2796 coreApps.add(pkg); 2797 } 2798 } 2799 2800 int[] stats = performDexOptUpgrade(coreApps, false, 2801 getCompilerFilterForReason(REASON_CORE_APP)); 2802 2803 final int elapsedTimeSeconds = 2804 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2805 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2806 2807 if (DEBUG_DEXOPT) { 2808 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2809 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2810 } 2811 2812 2813 // TODO: Should we log these stats to tron too ? 2814 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2815 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2816 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2817 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2818 } 2819 2820 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2821 SystemClock.uptimeMillis()); 2822 2823 if (!mOnlyCore) { 2824 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2825 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2826 mRequiredUninstallerPackage = getRequiredUninstallerLPr(); 2827 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2828 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2829 mIntentFilterVerifierComponent); 2830 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2831 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES, 2832 SharedLibraryInfo.VERSION_UNDEFINED); 2833 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2834 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED, 2835 SharedLibraryInfo.VERSION_UNDEFINED); 2836 } else { 2837 mRequiredVerifierPackage = null; 2838 mRequiredInstallerPackage = null; 2839 mRequiredUninstallerPackage = null; 2840 mIntentFilterVerifierComponent = null; 2841 mIntentFilterVerifier = null; 2842 mServicesSystemSharedLibraryPackageName = null; 2843 mSharedSystemSharedLibraryPackageName = null; 2844 } 2845 2846 mInstallerService = new PackageInstallerService(context, this); 2847 2848 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2849 if (ephemeralResolverComponent != null) { 2850 if (DEBUG_EPHEMERAL) { 2851 Slog.i(TAG, "Ephemeral resolver: " + ephemeralResolverComponent); 2852 } 2853 mEphemeralResolverConnection = 2854 new EphemeralResolverConnection(mContext, ephemeralResolverComponent); 2855 } else { 2856 mEphemeralResolverConnection = null; 2857 } 2858 mEphemeralInstallerComponent = getEphemeralInstallerLPr(); 2859 if (mEphemeralInstallerComponent != null) { 2860 if (DEBUG_EPHEMERAL) { 2861 Slog.i(TAG, "Ephemeral installer: " + mEphemeralInstallerComponent); 2862 } 2863 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2864 } 2865 2866 // Read and update the usage of dex files. 2867 // Do this at the end of PM init so that all the packages have their 2868 // data directory reconciled. 2869 // At this point we know the code paths of the packages, so we can validate 2870 // the disk file and build the internal cache. 2871 // The usage file is expected to be small so loading and verifying it 2872 // should take a fairly small time compare to the other activities (e.g. package 2873 // scanning). 2874 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>(); 2875 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 2876 for (int userId : currentUserIds) { 2877 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList()); 2878 } 2879 mDexManager.load(userPackages); 2880 } // synchronized (mPackages) 2881 } // synchronized (mInstallLock) 2882 2883 // Now after opening every single application zip, make sure they 2884 // are all flushed. Not really needed, but keeps things nice and 2885 // tidy. 2886 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC"); 2887 Runtime.getRuntime().gc(); 2888 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2889 2890 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks"); 2891 FallbackCategoryProvider.loadFallbacks(); 2892 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2893 2894 // The initial scanning above does many calls into installd while 2895 // holding the mPackages lock, but we're mostly interested in yelling 2896 // once we have a booted system. 2897 mInstaller.setWarnIfHeld(mPackages); 2898 2899 // Expose private service for system components to use. 2900 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2901 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2902 } 2903 2904 private static File preparePackageParserCache(boolean isUpgrade) { 2905 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { 2906 return null; 2907 } 2908 2909 // Disable package parsing on eng builds to allow for faster incremental development. 2910 if ("eng".equals(Build.TYPE)) { 2911 return null; 2912 } 2913 2914 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) { 2915 Slog.i(TAG, "Disabling package parser cache due to system property."); 2916 return null; 2917 } 2918 2919 // The base directory for the package parser cache lives under /data/system/. 2920 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(), 2921 "package_cache"); 2922 if (cacheBaseDir == null) { 2923 return null; 2924 } 2925 2926 // If this is a system upgrade scenario, delete the contents of the package cache dir. 2927 // This also serves to "GC" unused entries when the package cache version changes (which 2928 // can only happen during upgrades). 2929 if (isUpgrade) { 2930 FileUtils.deleteContents(cacheBaseDir); 2931 } 2932 2933 2934 // Return the versioned package cache directory. This is something like 2935 // "/data/system/package_cache/1" 2936 File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); 2937 2938 // The following is a workaround to aid development on non-numbered userdebug 2939 // builds or cases where "adb sync" is used on userdebug builds. If we detect that 2940 // the system partition is newer. 2941 // 2942 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build 2943 // that starts with "eng." to signify that this is an engineering build and not 2944 // destined for release. 2945 if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) { 2946 Slog.w(TAG, "Wiping cache directory because the system partition changed."); 2947 2948 // Heuristic: If the /system directory has been modified recently due to an "adb sync" 2949 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable 2950 // in general and should not be used for production changes. In this specific case, 2951 // we know that they will work. 2952 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2953 if (cacheDir.lastModified() < frameworkDir.lastModified()) { 2954 FileUtils.deleteContents(cacheBaseDir); 2955 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); 2956 } 2957 } 2958 2959 return cacheDir; 2960 } 2961 2962 @Override 2963 public boolean isFirstBoot() { 2964 return mFirstBoot; 2965 } 2966 2967 @Override 2968 public boolean isOnlyCoreApps() { 2969 return mOnlyCore; 2970 } 2971 2972 @Override 2973 public boolean isUpgrade() { 2974 return mIsUpgrade; 2975 } 2976 2977 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2978 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2979 2980 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2981 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2982 UserHandle.USER_SYSTEM); 2983 if (matches.size() == 1) { 2984 return matches.get(0).getComponentInfo().packageName; 2985 } else if (matches.size() == 0) { 2986 Log.e(TAG, "There should probably be a verifier, but, none were found"); 2987 return null; 2988 } 2989 throw new RuntimeException("There must be exactly one verifier; found " + matches); 2990 } 2991 2992 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) { 2993 synchronized (mPackages) { 2994 SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version); 2995 if (libraryEntry == null) { 2996 throw new IllegalStateException("Missing required shared library:" + name); 2997 } 2998 return libraryEntry.apk; 2999 } 3000 } 3001 3002 private @NonNull String getRequiredInstallerLPr() { 3003 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 3004 intent.addCategory(Intent.CATEGORY_DEFAULT); 3005 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 3006 3007 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 3008 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3009 UserHandle.USER_SYSTEM); 3010 if (matches.size() == 1) { 3011 ResolveInfo resolveInfo = matches.get(0); 3012 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 3013 throw new RuntimeException("The installer must be a privileged app"); 3014 } 3015 return matches.get(0).getComponentInfo().packageName; 3016 } else { 3017 throw new RuntimeException("There must be exactly one installer; found " + matches); 3018 } 3019 } 3020 3021 private @NonNull String getRequiredUninstallerLPr() { 3022 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 3023 intent.addCategory(Intent.CATEGORY_DEFAULT); 3024 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null)); 3025 3026 final ResolveInfo resolveInfo = resolveIntent(intent, null, 3027 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3028 UserHandle.USER_SYSTEM); 3029 if (resolveInfo == null || 3030 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) { 3031 throw new RuntimeException("There must be exactly one uninstaller; found " 3032 + resolveInfo); 3033 } 3034 return resolveInfo.getComponentInfo().packageName; 3035 } 3036 3037 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 3038 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 3039 3040 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 3041 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3042 UserHandle.USER_SYSTEM); 3043 ResolveInfo best = null; 3044 final int N = matches.size(); 3045 for (int i = 0; i < N; i++) { 3046 final ResolveInfo cur = matches.get(i); 3047 final String packageName = cur.getComponentInfo().packageName; 3048 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 3049 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 3050 continue; 3051 } 3052 3053 if (best == null || cur.priority > best.priority) { 3054 best = cur; 3055 } 3056 } 3057 3058 if (best != null) { 3059 return best.getComponentInfo().getComponentName(); 3060 } else { 3061 throw new RuntimeException("There must be at least one intent filter verifier"); 3062 } 3063 } 3064 3065 private @Nullable ComponentName getEphemeralResolverLPr() { 3066 final String[] packageArray = 3067 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 3068 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 3069 if (DEBUG_EPHEMERAL) { 3070 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 3071 } 3072 return null; 3073 } 3074 3075 final int resolveFlags = 3076 MATCH_DIRECT_BOOT_AWARE 3077 | MATCH_DIRECT_BOOT_UNAWARE 3078 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 3079 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 3080 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 3081 resolveFlags, UserHandle.USER_SYSTEM); 3082 3083 final int N = resolvers.size(); 3084 if (N == 0) { 3085 if (DEBUG_EPHEMERAL) { 3086 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 3087 } 3088 return null; 3089 } 3090 3091 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 3092 for (int i = 0; i < N; i++) { 3093 final ResolveInfo info = resolvers.get(i); 3094 3095 if (info.serviceInfo == null) { 3096 continue; 3097 } 3098 3099 final String packageName = info.serviceInfo.packageName; 3100 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 3101 if (DEBUG_EPHEMERAL) { 3102 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 3103 + " pkg: " + packageName + ", info:" + info); 3104 } 3105 continue; 3106 } 3107 3108 if (DEBUG_EPHEMERAL) { 3109 Slog.v(TAG, "Ephemeral resolver found;" 3110 + " pkg: " + packageName + ", info:" + info); 3111 } 3112 return new ComponentName(packageName, info.serviceInfo.name); 3113 } 3114 if (DEBUG_EPHEMERAL) { 3115 Slog.v(TAG, "Ephemeral resolver NOT found"); 3116 } 3117 return null; 3118 } 3119 3120 private @Nullable ComponentName getEphemeralInstallerLPr() { 3121 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 3122 intent.addCategory(Intent.CATEGORY_DEFAULT); 3123 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 3124 3125 final int resolveFlags = 3126 MATCH_DIRECT_BOOT_AWARE 3127 | MATCH_DIRECT_BOOT_UNAWARE 3128 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 3129 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 3130 resolveFlags, UserHandle.USER_SYSTEM); 3131 Iterator<ResolveInfo> iter = matches.iterator(); 3132 while (iter.hasNext()) { 3133 final ResolveInfo rInfo = iter.next(); 3134 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); 3135 if (ps != null) { 3136 final PermissionsState permissionsState = ps.getPermissionsState(); 3137 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) { 3138 continue; 3139 } 3140 } 3141 iter.remove(); 3142 } 3143 if (matches.size() == 0) { 3144 return null; 3145 } else if (matches.size() == 1) { 3146 return matches.get(0).getComponentInfo().getComponentName(); 3147 } else { 3148 throw new RuntimeException( 3149 "There must be at most one ephemeral installer; found " + matches); 3150 } 3151 } 3152 3153 private void primeDomainVerificationsLPw(int userId) { 3154 if (DEBUG_DOMAIN_VERIFICATION) { 3155 Slog.d(TAG, "Priming domain verifications in user " + userId); 3156 } 3157 3158 SystemConfig systemConfig = SystemConfig.getInstance(); 3159 ArraySet<String> packages = systemConfig.getLinkedApps(); 3160 3161 for (String packageName : packages) { 3162 PackageParser.Package pkg = mPackages.get(packageName); 3163 if (pkg != null) { 3164 if (!pkg.isSystemApp()) { 3165 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 3166 continue; 3167 } 3168 3169 ArraySet<String> domains = null; 3170 for (PackageParser.Activity a : pkg.activities) { 3171 for (ActivityIntentInfo filter : a.intents) { 3172 if (hasValidDomains(filter)) { 3173 if (domains == null) { 3174 domains = new ArraySet<String>(); 3175 } 3176 domains.addAll(filter.getHostsList()); 3177 } 3178 } 3179 } 3180 3181 if (domains != null && domains.size() > 0) { 3182 if (DEBUG_DOMAIN_VERIFICATION) { 3183 Slog.v(TAG, " + " + packageName); 3184 } 3185 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 3186 // state w.r.t. the formal app-linkage "no verification attempted" state; 3187 // and then 'always' in the per-user state actually used for intent resolution. 3188 final IntentFilterVerificationInfo ivi; 3189 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains); 3190 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 3191 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 3192 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 3193 } else { 3194 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 3195 + "' does not handle web links"); 3196 } 3197 } else { 3198 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 3199 } 3200 } 3201 3202 scheduleWritePackageRestrictionsLocked(userId); 3203 scheduleWriteSettingsLocked(); 3204 } 3205 3206 private void applyFactoryDefaultBrowserLPw(int userId) { 3207 // The default browser app's package name is stored in a string resource, 3208 // with a product-specific overlay used for vendor customization. 3209 String browserPkg = mContext.getResources().getString( 3210 com.android.internal.R.string.default_browser); 3211 if (!TextUtils.isEmpty(browserPkg)) { 3212 // non-empty string => required to be a known package 3213 PackageSetting ps = mSettings.mPackages.get(browserPkg); 3214 if (ps == null) { 3215 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 3216 browserPkg = null; 3217 } else { 3218 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3219 } 3220 } 3221 3222 // Nothing valid explicitly set? Make the factory-installed browser the explicit 3223 // default. If there's more than one, just leave everything alone. 3224 if (browserPkg == null) { 3225 calculateDefaultBrowserLPw(userId); 3226 } 3227 } 3228 3229 private void calculateDefaultBrowserLPw(int userId) { 3230 List<String> allBrowsers = resolveAllBrowserApps(userId); 3231 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 3232 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3233 } 3234 3235 private List<String> resolveAllBrowserApps(int userId) { 3236 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 3237 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3238 PackageManager.MATCH_ALL, userId); 3239 3240 final int count = list.size(); 3241 List<String> result = new ArrayList<String>(count); 3242 for (int i=0; i<count; i++) { 3243 ResolveInfo info = list.get(i); 3244 if (info.activityInfo == null 3245 || !info.handleAllWebDataURI 3246 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 3247 || result.contains(info.activityInfo.packageName)) { 3248 continue; 3249 } 3250 result.add(info.activityInfo.packageName); 3251 } 3252 3253 return result; 3254 } 3255 3256 private boolean packageIsBrowser(String packageName, int userId) { 3257 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3258 PackageManager.MATCH_ALL, userId); 3259 final int N = list.size(); 3260 for (int i = 0; i < N; i++) { 3261 ResolveInfo info = list.get(i); 3262 if (packageName.equals(info.activityInfo.packageName)) { 3263 return true; 3264 } 3265 } 3266 return false; 3267 } 3268 3269 private void checkDefaultBrowser() { 3270 final int myUserId = UserHandle.myUserId(); 3271 final String packageName = getDefaultBrowserPackageName(myUserId); 3272 if (packageName != null) { 3273 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 3274 if (info == null) { 3275 Slog.w(TAG, "Default browser no longer installed: " + packageName); 3276 synchronized (mPackages) { 3277 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 3278 } 3279 } 3280 } 3281 } 3282 3283 @Override 3284 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 3285 throws RemoteException { 3286 try { 3287 return super.onTransact(code, data, reply, flags); 3288 } catch (RuntimeException e) { 3289 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 3290 Slog.wtf(TAG, "Package Manager Crash", e); 3291 } 3292 throw e; 3293 } 3294 } 3295 3296 static int[] appendInts(int[] cur, int[] add) { 3297 if (add == null) return cur; 3298 if (cur == null) return add; 3299 final int N = add.length; 3300 for (int i=0; i<N; i++) { 3301 cur = appendInt(cur, add[i]); 3302 } 3303 return cur; 3304 } 3305 3306 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3307 if (!sUserManager.exists(userId)) return null; 3308 if (ps == null) { 3309 return null; 3310 } 3311 final PackageParser.Package p = ps.pkg; 3312 if (p == null) { 3313 return null; 3314 } 3315 // Filter out ephemeral app metadata: 3316 // * The system/shell/root can see metadata for any app 3317 // * An installed app can see metadata for 1) other installed apps 3318 // and 2) ephemeral apps that have explicitly interacted with it 3319 // * Ephemeral apps can only see their own metadata 3320 // * Holding a signature permission allows seeing instant apps 3321 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); 3322 if (callingAppId != Process.SYSTEM_UID 3323 && callingAppId != Process.SHELL_UID 3324 && callingAppId != Process.ROOT_UID 3325 && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS, 3326 Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) { 3327 final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid()); 3328 if (instantAppPackageName != null) { 3329 // ephemeral apps can only get information on themselves 3330 if (!instantAppPackageName.equals(p.packageName)) { 3331 return null; 3332 } 3333 } else { 3334 if (ps.getInstantApp(userId)) { 3335 // only get access to the ephemeral app if we've been granted access 3336 if (!mInstantAppRegistry.isInstantAccessGranted( 3337 userId, callingAppId, ps.appId)) { 3338 return null; 3339 } 3340 } 3341 } 3342 } 3343 3344 final PermissionsState permissionsState = ps.getPermissionsState(); 3345 3346 // Compute GIDs only if requested 3347 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3348 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3349 // Compute granted permissions only if package has requested permissions 3350 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3351 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3352 final PackageUserState state = ps.readUserState(userId); 3353 3354 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 3355 && ps.isSystem()) { 3356 flags |= MATCH_ANY_USER; 3357 } 3358 3359 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, 3360 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3361 3362 if (packageInfo == null) { 3363 return null; 3364 } 3365 3366 packageInfo.packageName = packageInfo.applicationInfo.packageName = 3367 resolveExternalPackageNameLPr(p); 3368 3369 return packageInfo; 3370 } 3371 3372 @Override 3373 public void checkPackageStartable(String packageName, int userId) { 3374 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3375 3376 synchronized (mPackages) { 3377 final PackageSetting ps = mSettings.mPackages.get(packageName); 3378 if (ps == null) { 3379 throw new SecurityException("Package " + packageName + " was not found!"); 3380 } 3381 3382 if (!ps.getInstalled(userId)) { 3383 throw new SecurityException( 3384 "Package " + packageName + " was not installed for user " + userId + "!"); 3385 } 3386 3387 if (mSafeMode && !ps.isSystem()) { 3388 throw new SecurityException("Package " + packageName + " not a system app!"); 3389 } 3390 3391 if (mFrozenPackages.contains(packageName)) { 3392 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3393 } 3394 3395 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3396 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3397 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3398 } 3399 } 3400 } 3401 3402 @Override 3403 public boolean isPackageAvailable(String packageName, int userId) { 3404 if (!sUserManager.exists(userId)) return false; 3405 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3406 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3407 synchronized (mPackages) { 3408 PackageParser.Package p = mPackages.get(packageName); 3409 if (p != null) { 3410 final PackageSetting ps = (PackageSetting) p.mExtras; 3411 if (ps != null) { 3412 final PackageUserState state = ps.readUserState(userId); 3413 if (state != null) { 3414 return PackageParser.isAvailable(state); 3415 } 3416 } 3417 } 3418 } 3419 return false; 3420 } 3421 3422 @Override 3423 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3424 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST, 3425 flags, userId); 3426 } 3427 3428 @Override 3429 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage, 3430 int flags, int userId) { 3431 return getPackageInfoInternal(versionedPackage.getPackageName(), 3432 // TODO: We will change version code to long, so in the new API it is long 3433 (int) versionedPackage.getVersionCode(), flags, userId); 3434 } 3435 3436 private PackageInfo getPackageInfoInternal(String packageName, int versionCode, 3437 int flags, int userId) { 3438 if (!sUserManager.exists(userId)) return null; 3439 flags = updateFlagsForPackage(flags, userId, packageName); 3440 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3441 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3442 3443 // reader 3444 synchronized (mPackages) { 3445 // Normalize package name to handle renamed packages and static libs 3446 packageName = resolveInternalPackageNameLPr(packageName, versionCode); 3447 3448 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3449 if (matchFactoryOnly) { 3450 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3451 if (ps != null) { 3452 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3453 return null; 3454 } 3455 return generatePackageInfo(ps, flags, userId); 3456 } 3457 } 3458 3459 PackageParser.Package p = mPackages.get(packageName); 3460 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3461 return null; 3462 } 3463 if (DEBUG_PACKAGE_INFO) 3464 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3465 if (p != null) { 3466 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras, 3467 Binder.getCallingUid(), userId)) { 3468 return null; 3469 } 3470 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3471 } 3472 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) { 3473 final PackageSetting ps = mSettings.mPackages.get(packageName); 3474 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3475 return null; 3476 } 3477 return generatePackageInfo(ps, flags, userId); 3478 } 3479 } 3480 return null; 3481 } 3482 3483 3484 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) { 3485 // System/shell/root get to see all static libs 3486 final int appId = UserHandle.getAppId(uid); 3487 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID 3488 || appId == Process.ROOT_UID) { 3489 return false; 3490 } 3491 3492 // No package means no static lib as it is always on internal storage 3493 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) { 3494 return false; 3495 } 3496 3497 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName, 3498 ps.pkg.staticSharedLibVersion); 3499 if (libEntry == null) { 3500 return false; 3501 } 3502 3503 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 3504 final String[] uidPackageNames = getPackagesForUid(resolvedUid); 3505 if (uidPackageNames == null) { 3506 return true; 3507 } 3508 3509 for (String uidPackageName : uidPackageNames) { 3510 if (ps.name.equals(uidPackageName)) { 3511 return false; 3512 } 3513 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName); 3514 if (uidPs != null) { 3515 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries, 3516 libEntry.info.getName()); 3517 if (index < 0) { 3518 continue; 3519 } 3520 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) { 3521 return false; 3522 } 3523 } 3524 } 3525 return true; 3526 } 3527 3528 @Override 3529 public String[] currentToCanonicalPackageNames(String[] names) { 3530 String[] out = new String[names.length]; 3531 // reader 3532 synchronized (mPackages) { 3533 for (int i=names.length-1; i>=0; i--) { 3534 PackageSetting ps = mSettings.mPackages.get(names[i]); 3535 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3536 } 3537 } 3538 return out; 3539 } 3540 3541 @Override 3542 public String[] canonicalToCurrentPackageNames(String[] names) { 3543 String[] out = new String[names.length]; 3544 // reader 3545 synchronized (mPackages) { 3546 for (int i=names.length-1; i>=0; i--) { 3547 String cur = mSettings.getRenamedPackageLPr(names[i]); 3548 out[i] = cur != null ? cur : names[i]; 3549 } 3550 } 3551 return out; 3552 } 3553 3554 @Override 3555 public int getPackageUid(String packageName, int flags, int userId) { 3556 if (!sUserManager.exists(userId)) return -1; 3557 flags = updateFlagsForPackage(flags, userId, packageName); 3558 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3559 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3560 3561 // reader 3562 synchronized (mPackages) { 3563 final PackageParser.Package p = mPackages.get(packageName); 3564 if (p != null && p.isMatch(flags)) { 3565 return UserHandle.getUid(userId, p.applicationInfo.uid); 3566 } 3567 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3568 final PackageSetting ps = mSettings.mPackages.get(packageName); 3569 if (ps != null && ps.isMatch(flags)) { 3570 return UserHandle.getUid(userId, ps.appId); 3571 } 3572 } 3573 } 3574 3575 return -1; 3576 } 3577 3578 @Override 3579 public int[] getPackageGids(String packageName, int flags, int userId) { 3580 if (!sUserManager.exists(userId)) return null; 3581 flags = updateFlagsForPackage(flags, userId, packageName); 3582 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3583 false /* requireFullPermission */, false /* checkShell */, 3584 "getPackageGids"); 3585 3586 // reader 3587 synchronized (mPackages) { 3588 final PackageParser.Package p = mPackages.get(packageName); 3589 if (p != null && p.isMatch(flags)) { 3590 PackageSetting ps = (PackageSetting) p.mExtras; 3591 // TODO: Shouldn't this be checking for package installed state for userId and 3592 // return null? 3593 return ps.getPermissionsState().computeGids(userId); 3594 } 3595 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3596 final PackageSetting ps = mSettings.mPackages.get(packageName); 3597 if (ps != null && ps.isMatch(flags)) { 3598 return ps.getPermissionsState().computeGids(userId); 3599 } 3600 } 3601 } 3602 3603 return null; 3604 } 3605 3606 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3607 if (bp.perm != null) { 3608 return PackageParser.generatePermissionInfo(bp.perm, flags); 3609 } 3610 PermissionInfo pi = new PermissionInfo(); 3611 pi.name = bp.name; 3612 pi.packageName = bp.sourcePackage; 3613 pi.nonLocalizedLabel = bp.name; 3614 pi.protectionLevel = bp.protectionLevel; 3615 return pi; 3616 } 3617 3618 @Override 3619 public PermissionInfo getPermissionInfo(String name, int flags) { 3620 // reader 3621 synchronized (mPackages) { 3622 final BasePermission p = mSettings.mPermissions.get(name); 3623 if (p != null) { 3624 return generatePermissionInfo(p, flags); 3625 } 3626 return null; 3627 } 3628 } 3629 3630 @Override 3631 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3632 int flags) { 3633 // reader 3634 synchronized (mPackages) { 3635 if (group != null && !mPermissionGroups.containsKey(group)) { 3636 // This is thrown as NameNotFoundException 3637 return null; 3638 } 3639 3640 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3641 for (BasePermission p : mSettings.mPermissions.values()) { 3642 if (group == null) { 3643 if (p.perm == null || p.perm.info.group == null) { 3644 out.add(generatePermissionInfo(p, flags)); 3645 } 3646 } else { 3647 if (p.perm != null && group.equals(p.perm.info.group)) { 3648 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3649 } 3650 } 3651 } 3652 return new ParceledListSlice<>(out); 3653 } 3654 } 3655 3656 @Override 3657 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3658 // reader 3659 synchronized (mPackages) { 3660 return PackageParser.generatePermissionGroupInfo( 3661 mPermissionGroups.get(name), flags); 3662 } 3663 } 3664 3665 @Override 3666 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3667 // reader 3668 synchronized (mPackages) { 3669 final int N = mPermissionGroups.size(); 3670 ArrayList<PermissionGroupInfo> out 3671 = new ArrayList<PermissionGroupInfo>(N); 3672 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3673 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3674 } 3675 return new ParceledListSlice<>(out); 3676 } 3677 } 3678 3679 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3680 int uid, int userId) { 3681 if (!sUserManager.exists(userId)) return null; 3682 PackageSetting ps = mSettings.mPackages.get(packageName); 3683 if (ps != null) { 3684 if (filterSharedLibPackageLPr(ps, uid, userId)) { 3685 return null; 3686 } 3687 if (ps.pkg == null) { 3688 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3689 if (pInfo != null) { 3690 return pInfo.applicationInfo; 3691 } 3692 return null; 3693 } 3694 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 3695 ps.readUserState(userId), userId); 3696 if (ai != null) { 3697 ai.packageName = resolveExternalPackageNameLPr(ps.pkg); 3698 } 3699 return ai; 3700 } 3701 return null; 3702 } 3703 3704 @Override 3705 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3706 if (!sUserManager.exists(userId)) return null; 3707 flags = updateFlagsForApplication(flags, userId, packageName); 3708 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3709 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3710 3711 // writer 3712 synchronized (mPackages) { 3713 // Normalize package name to handle renamed packages and static libs 3714 packageName = resolveInternalPackageNameLPr(packageName, 3715 PackageManager.VERSION_CODE_HIGHEST); 3716 3717 PackageParser.Package p = mPackages.get(packageName); 3718 if (DEBUG_PACKAGE_INFO) Log.v( 3719 TAG, "getApplicationInfo " + packageName 3720 + ": " + p); 3721 if (p != null) { 3722 PackageSetting ps = mSettings.mPackages.get(packageName); 3723 if (ps == null) return null; 3724 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3725 return null; 3726 } 3727 // Note: isEnabledLP() does not apply here - always return info 3728 ApplicationInfo ai = PackageParser.generateApplicationInfo( 3729 p, flags, ps.readUserState(userId), userId); 3730 if (ai != null) { 3731 ai.packageName = resolveExternalPackageNameLPr(p); 3732 } 3733 return ai; 3734 } 3735 if ("android".equals(packageName)||"system".equals(packageName)) { 3736 return mAndroidApplication; 3737 } 3738 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3739 // Already generates the external package name 3740 return generateApplicationInfoFromSettingsLPw(packageName, 3741 Binder.getCallingUid(), flags, userId); 3742 } 3743 } 3744 return null; 3745 } 3746 3747 private String normalizePackageNameLPr(String packageName) { 3748 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName); 3749 return normalizedPackageName != null ? normalizedPackageName : packageName; 3750 } 3751 3752 @Override 3753 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3754 final IPackageDataObserver observer) { 3755 mContext.enforceCallingOrSelfPermission( 3756 android.Manifest.permission.CLEAR_APP_CACHE, null); 3757 // Queue up an async operation since clearing cache may take a little while. 3758 mHandler.post(new Runnable() { 3759 public void run() { 3760 mHandler.removeCallbacks(this); 3761 boolean success = true; 3762 synchronized (mInstallLock) { 3763 try { 3764 mInstaller.freeCache(volumeUuid, freeStorageSize, 0); 3765 } catch (InstallerException e) { 3766 Slog.w(TAG, "Couldn't clear application caches: " + e); 3767 success = false; 3768 } 3769 } 3770 if (observer != null) { 3771 try { 3772 observer.onRemoveCompleted(null, success); 3773 } catch (RemoteException e) { 3774 Slog.w(TAG, "RemoveException when invoking call back"); 3775 } 3776 } 3777 } 3778 }); 3779 } 3780 3781 @Override 3782 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3783 final IntentSender pi) { 3784 mContext.enforceCallingOrSelfPermission( 3785 android.Manifest.permission.CLEAR_APP_CACHE, null); 3786 // Queue up an async operation since clearing cache may take a little while. 3787 mHandler.post(new Runnable() { 3788 public void run() { 3789 mHandler.removeCallbacks(this); 3790 boolean success = true; 3791 synchronized (mInstallLock) { 3792 try { 3793 mInstaller.freeCache(volumeUuid, freeStorageSize, 0); 3794 } catch (InstallerException e) { 3795 Slog.w(TAG, "Couldn't clear application caches: " + e); 3796 success = false; 3797 } 3798 } 3799 if(pi != null) { 3800 try { 3801 // Callback via pending intent 3802 int code = success ? 1 : 0; 3803 pi.sendIntent(null, code, null, 3804 null, null); 3805 } catch (SendIntentException e1) { 3806 Slog.i(TAG, "Failed to send pending intent"); 3807 } 3808 } 3809 } 3810 }); 3811 } 3812 3813 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3814 synchronized (mInstallLock) { 3815 try { 3816 mInstaller.freeCache(volumeUuid, freeStorageSize, 0); 3817 } catch (InstallerException e) { 3818 throw new IOException("Failed to free enough space", e); 3819 } 3820 } 3821 } 3822 3823 /** 3824 * Update given flags based on encryption status of current user. 3825 */ 3826 private int updateFlags(int flags, int userId) { 3827 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3828 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3829 // Caller expressed an explicit opinion about what encryption 3830 // aware/unaware components they want to see, so fall through and 3831 // give them what they want 3832 } else { 3833 // Caller expressed no opinion, so match based on user state 3834 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3835 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3836 } else { 3837 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3838 } 3839 } 3840 return flags; 3841 } 3842 3843 private UserManagerInternal getUserManagerInternal() { 3844 if (mUserManagerInternal == null) { 3845 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3846 } 3847 return mUserManagerInternal; 3848 } 3849 3850 /** 3851 * Update given flags when being used to request {@link PackageInfo}. 3852 */ 3853 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3854 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM; 3855 boolean triaged = true; 3856 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3857 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3858 // Caller is asking for component details, so they'd better be 3859 // asking for specific encryption matching behavior, or be triaged 3860 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3861 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3862 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3863 triaged = false; 3864 } 3865 } 3866 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3867 | PackageManager.MATCH_SYSTEM_ONLY 3868 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3869 triaged = false; 3870 } 3871 if ((flags & PackageManager.MATCH_ANY_USER) != 0) { 3872 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 3873 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at " 3874 + Debug.getCallers(5)); 3875 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser 3876 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) { 3877 // If the caller wants all packages and has a restricted profile associated with it, 3878 // then match all users. This is to make sure that launchers that need to access work 3879 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using 3880 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380 3881 flags |= PackageManager.MATCH_ANY_USER; 3882 } 3883 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3884 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3885 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3886 } 3887 return updateFlags(flags, userId); 3888 } 3889 3890 /** 3891 * Update given flags when being used to request {@link ApplicationInfo}. 3892 */ 3893 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3894 return updateFlagsForPackage(flags, userId, cookie); 3895 } 3896 3897 /** 3898 * Update given flags when being used to request {@link ComponentInfo}. 3899 */ 3900 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3901 if (cookie instanceof Intent) { 3902 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3903 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3904 } 3905 } 3906 3907 boolean triaged = true; 3908 // Caller is asking for component details, so they'd better be 3909 // asking for specific encryption matching behavior, or be triaged 3910 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3911 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3912 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3913 triaged = false; 3914 } 3915 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3916 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3917 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3918 } 3919 3920 return updateFlags(flags, userId); 3921 } 3922 3923 /** 3924 * Update given intent when being used to request {@link ResolveInfo}. 3925 */ 3926 private Intent updateIntentForResolve(Intent intent) { 3927 if (intent.getSelector() != null) { 3928 intent = intent.getSelector(); 3929 } 3930 if (DEBUG_PREFERRED) { 3931 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3932 } 3933 return intent; 3934 } 3935 3936 /** 3937 * Update given flags when being used to request {@link ResolveInfo}. 3938 */ 3939 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3940 // Safe mode means we shouldn't match any third-party components 3941 if (mSafeMode) { 3942 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3943 } 3944 final int callingUid = Binder.getCallingUid(); 3945 if (getInstantAppPackageName(callingUid) != null) { 3946 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components 3947 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; 3948 flags |= PackageManager.MATCH_INSTANT; 3949 } else { 3950 // Otherwise, prevent leaking ephemeral components 3951 flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; 3952 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3953 // Unless called from the system process 3954 flags &= ~PackageManager.MATCH_INSTANT; 3955 } 3956 } 3957 return updateFlagsForComponent(flags, userId, cookie); 3958 } 3959 3960 @Override 3961 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3962 if (!sUserManager.exists(userId)) return null; 3963 flags = updateFlagsForComponent(flags, userId, component); 3964 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3965 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3966 synchronized (mPackages) { 3967 PackageParser.Activity a = mActivities.mActivities.get(component); 3968 3969 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3970 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3971 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3972 if (ps == null) return null; 3973 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3974 userId); 3975 } 3976 if (mResolveComponentName.equals(component)) { 3977 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3978 new PackageUserState(), userId); 3979 } 3980 } 3981 return null; 3982 } 3983 3984 @Override 3985 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3986 String resolvedType) { 3987 synchronized (mPackages) { 3988 if (component.equals(mResolveComponentName)) { 3989 // The resolver supports EVERYTHING! 3990 return true; 3991 } 3992 PackageParser.Activity a = mActivities.mActivities.get(component); 3993 if (a == null) { 3994 return false; 3995 } 3996 for (int i=0; i<a.intents.size(); i++) { 3997 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3998 intent.getData(), intent.getCategories(), TAG) >= 0) { 3999 return true; 4000 } 4001 } 4002 return false; 4003 } 4004 } 4005 4006 @Override 4007 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 4008 if (!sUserManager.exists(userId)) return null; 4009 flags = updateFlagsForComponent(flags, userId, component); 4010 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4011 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 4012 synchronized (mPackages) { 4013 PackageParser.Activity a = mReceivers.mActivities.get(component); 4014 if (DEBUG_PACKAGE_INFO) Log.v( 4015 TAG, "getReceiverInfo " + component + ": " + a); 4016 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 4017 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4018 if (ps == null) return null; 4019 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 4020 userId); 4021 } 4022 } 4023 return null; 4024 } 4025 4026 @Override 4027 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) { 4028 if (!sUserManager.exists(userId)) return null; 4029 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0"); 4030 4031 flags = updateFlagsForPackage(flags, userId, null); 4032 4033 final boolean canSeeStaticLibraries = 4034 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES) 4035 == PERMISSION_GRANTED 4036 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES) 4037 == PERMISSION_GRANTED 4038 || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES) 4039 == PERMISSION_GRANTED 4040 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES) 4041 == PERMISSION_GRANTED; 4042 4043 synchronized (mPackages) { 4044 List<SharedLibraryInfo> result = null; 4045 4046 final int libCount = mSharedLibraries.size(); 4047 for (int i = 0; i < libCount; i++) { 4048 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 4049 if (versionedLib == null) { 4050 continue; 4051 } 4052 4053 final int versionCount = versionedLib.size(); 4054 for (int j = 0; j < versionCount; j++) { 4055 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info; 4056 if (!canSeeStaticLibraries && libInfo.isStatic()) { 4057 break; 4058 } 4059 final long identity = Binder.clearCallingIdentity(); 4060 try { 4061 // TODO: We will change version code to long, so in the new API it is long 4062 PackageInfo packageInfo = getPackageInfoVersioned( 4063 libInfo.getDeclaringPackage(), flags, userId); 4064 if (packageInfo == null) { 4065 continue; 4066 } 4067 } finally { 4068 Binder.restoreCallingIdentity(identity); 4069 } 4070 4071 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(), 4072 libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(), 4073 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId)); 4074 4075 if (result == null) { 4076 result = new ArrayList<>(); 4077 } 4078 result.add(resLibInfo); 4079 } 4080 } 4081 4082 return result != null ? new ParceledListSlice<>(result) : null; 4083 } 4084 } 4085 4086 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr( 4087 SharedLibraryInfo libInfo, int flags, int userId) { 4088 List<VersionedPackage> versionedPackages = null; 4089 final int packageCount = mSettings.mPackages.size(); 4090 for (int i = 0; i < packageCount; i++) { 4091 PackageSetting ps = mSettings.mPackages.valueAt(i); 4092 4093 if (ps == null) { 4094 continue; 4095 } 4096 4097 if (!ps.getUserState().get(userId).isAvailable(flags)) { 4098 continue; 4099 } 4100 4101 final String libName = libInfo.getName(); 4102 if (libInfo.isStatic()) { 4103 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName); 4104 if (libIdx < 0) { 4105 continue; 4106 } 4107 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) { 4108 continue; 4109 } 4110 if (versionedPackages == null) { 4111 versionedPackages = new ArrayList<>(); 4112 } 4113 // If the dependent is a static shared lib, use the public package name 4114 String dependentPackageName = ps.name; 4115 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) { 4116 dependentPackageName = ps.pkg.manifestPackageName; 4117 } 4118 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode)); 4119 } else if (ps.pkg != null) { 4120 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName) 4121 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) { 4122 if (versionedPackages == null) { 4123 versionedPackages = new ArrayList<>(); 4124 } 4125 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode)); 4126 } 4127 } 4128 } 4129 4130 return versionedPackages; 4131 } 4132 4133 @Override 4134 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 4135 if (!sUserManager.exists(userId)) return null; 4136 flags = updateFlagsForComponent(flags, userId, component); 4137 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4138 false /* requireFullPermission */, false /* checkShell */, "get service info"); 4139 synchronized (mPackages) { 4140 PackageParser.Service s = mServices.mServices.get(component); 4141 if (DEBUG_PACKAGE_INFO) Log.v( 4142 TAG, "getServiceInfo " + component + ": " + s); 4143 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 4144 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4145 if (ps == null) return null; 4146 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 4147 userId); 4148 } 4149 } 4150 return null; 4151 } 4152 4153 @Override 4154 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 4155 if (!sUserManager.exists(userId)) return null; 4156 flags = updateFlagsForComponent(flags, userId, component); 4157 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4158 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 4159 synchronized (mPackages) { 4160 PackageParser.Provider p = mProviders.mProviders.get(component); 4161 if (DEBUG_PACKAGE_INFO) Log.v( 4162 TAG, "getProviderInfo " + component + ": " + p); 4163 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 4164 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4165 if (ps == null) return null; 4166 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 4167 userId); 4168 } 4169 } 4170 return null; 4171 } 4172 4173 @Override 4174 public String[] getSystemSharedLibraryNames() { 4175 synchronized (mPackages) { 4176 Set<String> libs = null; 4177 final int libCount = mSharedLibraries.size(); 4178 for (int i = 0; i < libCount; i++) { 4179 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 4180 if (versionedLib == null) { 4181 continue; 4182 } 4183 final int versionCount = versionedLib.size(); 4184 for (int j = 0; j < versionCount; j++) { 4185 SharedLibraryEntry libEntry = versionedLib.valueAt(j); 4186 if (!libEntry.info.isStatic()) { 4187 if (libs == null) { 4188 libs = new ArraySet<>(); 4189 } 4190 libs.add(libEntry.info.getName()); 4191 break; 4192 } 4193 PackageSetting ps = mSettings.getPackageLPr(libEntry.apk); 4194 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(), 4195 UserHandle.getUserId(Binder.getCallingUid()))) { 4196 if (libs == null) { 4197 libs = new ArraySet<>(); 4198 } 4199 libs.add(libEntry.info.getName()); 4200 break; 4201 } 4202 } 4203 } 4204 4205 if (libs != null) { 4206 String[] libsArray = new String[libs.size()]; 4207 libs.toArray(libsArray); 4208 return libsArray; 4209 } 4210 4211 return null; 4212 } 4213 } 4214 4215 @Override 4216 public @NonNull String getServicesSystemSharedLibraryPackageName() { 4217 synchronized (mPackages) { 4218 return mServicesSystemSharedLibraryPackageName; 4219 } 4220 } 4221 4222 @Override 4223 public @NonNull String getSharedSystemSharedLibraryPackageName() { 4224 synchronized (mPackages) { 4225 return mSharedSystemSharedLibraryPackageName; 4226 } 4227 } 4228 4229 @Override 4230 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 4231 ArrayList<FeatureInfo> res; 4232 synchronized (mAvailableFeatures) { 4233 res = new ArrayList<>(mAvailableFeatures.size() + 1); 4234 res.addAll(mAvailableFeatures.values()); 4235 } 4236 final FeatureInfo fi = new FeatureInfo(); 4237 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 4238 FeatureInfo.GL_ES_VERSION_UNDEFINED); 4239 res.add(fi); 4240 4241 return new ParceledListSlice<>(res); 4242 } 4243 4244 @Override 4245 public boolean hasSystemFeature(String name, int version) { 4246 synchronized (mAvailableFeatures) { 4247 final FeatureInfo feat = mAvailableFeatures.get(name); 4248 if (feat == null) { 4249 return false; 4250 } else { 4251 return feat.version >= version; 4252 } 4253 } 4254 } 4255 4256 @Override 4257 public int checkPermission(String permName, String pkgName, int userId) { 4258 if (!sUserManager.exists(userId)) { 4259 return PackageManager.PERMISSION_DENIED; 4260 } 4261 4262 synchronized (mPackages) { 4263 final PackageParser.Package p = mPackages.get(pkgName); 4264 if (p != null && p.mExtras != null) { 4265 final PackageSetting ps = (PackageSetting) p.mExtras; 4266 final PermissionsState permissionsState = ps.getPermissionsState(); 4267 if (permissionsState.hasPermission(permName, userId)) { 4268 return PackageManager.PERMISSION_GRANTED; 4269 } 4270 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 4271 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 4272 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 4273 return PackageManager.PERMISSION_GRANTED; 4274 } 4275 } 4276 } 4277 4278 return PackageManager.PERMISSION_DENIED; 4279 } 4280 4281 @Override 4282 public int checkUidPermission(String permName, int uid) { 4283 final int userId = UserHandle.getUserId(uid); 4284 4285 if (!sUserManager.exists(userId)) { 4286 return PackageManager.PERMISSION_DENIED; 4287 } 4288 4289 synchronized (mPackages) { 4290 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4291 if (obj != null) { 4292 final SettingBase ps = (SettingBase) obj; 4293 final PermissionsState permissionsState = ps.getPermissionsState(); 4294 if (permissionsState.hasPermission(permName, userId)) { 4295 return PackageManager.PERMISSION_GRANTED; 4296 } 4297 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 4298 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 4299 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 4300 return PackageManager.PERMISSION_GRANTED; 4301 } 4302 } else { 4303 ArraySet<String> perms = mSystemPermissions.get(uid); 4304 if (perms != null) { 4305 if (perms.contains(permName)) { 4306 return PackageManager.PERMISSION_GRANTED; 4307 } 4308 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 4309 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 4310 return PackageManager.PERMISSION_GRANTED; 4311 } 4312 } 4313 } 4314 } 4315 4316 return PackageManager.PERMISSION_DENIED; 4317 } 4318 4319 @Override 4320 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 4321 if (UserHandle.getCallingUserId() != userId) { 4322 mContext.enforceCallingPermission( 4323 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4324 "isPermissionRevokedByPolicy for user " + userId); 4325 } 4326 4327 if (checkPermission(permission, packageName, userId) 4328 == PackageManager.PERMISSION_GRANTED) { 4329 return false; 4330 } 4331 4332 final long identity = Binder.clearCallingIdentity(); 4333 try { 4334 final int flags = getPermissionFlags(permission, packageName, userId); 4335 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 4336 } finally { 4337 Binder.restoreCallingIdentity(identity); 4338 } 4339 } 4340 4341 @Override 4342 public String getPermissionControllerPackageName() { 4343 synchronized (mPackages) { 4344 return mRequiredInstallerPackage; 4345 } 4346 } 4347 4348 /** 4349 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 4350 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 4351 * @param checkShell whether to prevent shell from access if there's a debugging restriction 4352 * @param message the message to log on security exception 4353 */ 4354 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 4355 boolean checkShell, String message) { 4356 if (userId < 0) { 4357 throw new IllegalArgumentException("Invalid userId " + userId); 4358 } 4359 if (checkShell) { 4360 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 4361 } 4362 if (userId == UserHandle.getUserId(callingUid)) return; 4363 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4364 if (requireFullPermission) { 4365 mContext.enforceCallingOrSelfPermission( 4366 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 4367 } else { 4368 try { 4369 mContext.enforceCallingOrSelfPermission( 4370 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 4371 } catch (SecurityException se) { 4372 mContext.enforceCallingOrSelfPermission( 4373 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 4374 } 4375 } 4376 } 4377 } 4378 4379 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 4380 if (callingUid == Process.SHELL_UID) { 4381 if (userHandle >= 0 4382 && sUserManager.hasUserRestriction(restriction, userHandle)) { 4383 throw new SecurityException("Shell does not have permission to access user " 4384 + userHandle); 4385 } else if (userHandle < 0) { 4386 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 4387 + Debug.getCallers(3)); 4388 } 4389 } 4390 } 4391 4392 private BasePermission findPermissionTreeLP(String permName) { 4393 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 4394 if (permName.startsWith(bp.name) && 4395 permName.length() > bp.name.length() && 4396 permName.charAt(bp.name.length()) == '.') { 4397 return bp; 4398 } 4399 } 4400 return null; 4401 } 4402 4403 private BasePermission checkPermissionTreeLP(String permName) { 4404 if (permName != null) { 4405 BasePermission bp = findPermissionTreeLP(permName); 4406 if (bp != null) { 4407 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 4408 return bp; 4409 } 4410 throw new SecurityException("Calling uid " 4411 + Binder.getCallingUid() 4412 + " is not allowed to add to permission tree " 4413 + bp.name + " owned by uid " + bp.uid); 4414 } 4415 } 4416 throw new SecurityException("No permission tree found for " + permName); 4417 } 4418 4419 static boolean compareStrings(CharSequence s1, CharSequence s2) { 4420 if (s1 == null) { 4421 return s2 == null; 4422 } 4423 if (s2 == null) { 4424 return false; 4425 } 4426 if (s1.getClass() != s2.getClass()) { 4427 return false; 4428 } 4429 return s1.equals(s2); 4430 } 4431 4432 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 4433 if (pi1.icon != pi2.icon) return false; 4434 if (pi1.logo != pi2.logo) return false; 4435 if (pi1.protectionLevel != pi2.protectionLevel) return false; 4436 if (!compareStrings(pi1.name, pi2.name)) return false; 4437 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 4438 // We'll take care of setting this one. 4439 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 4440 // These are not currently stored in settings. 4441 //if (!compareStrings(pi1.group, pi2.group)) return false; 4442 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 4443 //if (pi1.labelRes != pi2.labelRes) return false; 4444 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 4445 return true; 4446 } 4447 4448 int permissionInfoFootprint(PermissionInfo info) { 4449 int size = info.name.length(); 4450 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 4451 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 4452 return size; 4453 } 4454 4455 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 4456 int size = 0; 4457 for (BasePermission perm : mSettings.mPermissions.values()) { 4458 if (perm.uid == tree.uid) { 4459 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 4460 } 4461 } 4462 return size; 4463 } 4464 4465 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 4466 // We calculate the max size of permissions defined by this uid and throw 4467 // if that plus the size of 'info' would exceed our stated maximum. 4468 if (tree.uid != Process.SYSTEM_UID) { 4469 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 4470 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 4471 throw new SecurityException("Permission tree size cap exceeded"); 4472 } 4473 } 4474 } 4475 4476 boolean addPermissionLocked(PermissionInfo info, boolean async) { 4477 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 4478 throw new SecurityException("Label must be specified in permission"); 4479 } 4480 BasePermission tree = checkPermissionTreeLP(info.name); 4481 BasePermission bp = mSettings.mPermissions.get(info.name); 4482 boolean added = bp == null; 4483 boolean changed = true; 4484 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 4485 if (added) { 4486 enforcePermissionCapLocked(info, tree); 4487 bp = new BasePermission(info.name, tree.sourcePackage, 4488 BasePermission.TYPE_DYNAMIC); 4489 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 4490 throw new SecurityException( 4491 "Not allowed to modify non-dynamic permission " 4492 + info.name); 4493 } else { 4494 if (bp.protectionLevel == fixedLevel 4495 && bp.perm.owner.equals(tree.perm.owner) 4496 && bp.uid == tree.uid 4497 && comparePermissionInfos(bp.perm.info, info)) { 4498 changed = false; 4499 } 4500 } 4501 bp.protectionLevel = fixedLevel; 4502 info = new PermissionInfo(info); 4503 info.protectionLevel = fixedLevel; 4504 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 4505 bp.perm.info.packageName = tree.perm.info.packageName; 4506 bp.uid = tree.uid; 4507 if (added) { 4508 mSettings.mPermissions.put(info.name, bp); 4509 } 4510 if (changed) { 4511 if (!async) { 4512 mSettings.writeLPr(); 4513 } else { 4514 scheduleWriteSettingsLocked(); 4515 } 4516 } 4517 return added; 4518 } 4519 4520 @Override 4521 public boolean addPermission(PermissionInfo info) { 4522 synchronized (mPackages) { 4523 return addPermissionLocked(info, false); 4524 } 4525 } 4526 4527 @Override 4528 public boolean addPermissionAsync(PermissionInfo info) { 4529 synchronized (mPackages) { 4530 return addPermissionLocked(info, true); 4531 } 4532 } 4533 4534 @Override 4535 public void removePermission(String name) { 4536 synchronized (mPackages) { 4537 checkPermissionTreeLP(name); 4538 BasePermission bp = mSettings.mPermissions.get(name); 4539 if (bp != null) { 4540 if (bp.type != BasePermission.TYPE_DYNAMIC) { 4541 throw new SecurityException( 4542 "Not allowed to modify non-dynamic permission " 4543 + name); 4544 } 4545 mSettings.mPermissions.remove(name); 4546 mSettings.writeLPr(); 4547 } 4548 } 4549 } 4550 4551 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 4552 BasePermission bp) { 4553 int index = pkg.requestedPermissions.indexOf(bp.name); 4554 if (index == -1) { 4555 throw new SecurityException("Package " + pkg.packageName 4556 + " has not requested permission " + bp.name); 4557 } 4558 if (!bp.isRuntime() && !bp.isDevelopment()) { 4559 throw new SecurityException("Permission " + bp.name 4560 + " is not a changeable permission type"); 4561 } 4562 } 4563 4564 @Override 4565 public void grantRuntimePermission(String packageName, String name, final int userId) { 4566 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4567 } 4568 4569 private void grantRuntimePermission(String packageName, String name, final int userId, 4570 boolean overridePolicy) { 4571 if (!sUserManager.exists(userId)) { 4572 Log.e(TAG, "No such user:" + userId); 4573 return; 4574 } 4575 4576 mContext.enforceCallingOrSelfPermission( 4577 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 4578 "grantRuntimePermission"); 4579 4580 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4581 true /* requireFullPermission */, true /* checkShell */, 4582 "grantRuntimePermission"); 4583 4584 final int uid; 4585 final SettingBase sb; 4586 4587 synchronized (mPackages) { 4588 final PackageParser.Package pkg = mPackages.get(packageName); 4589 if (pkg == null) { 4590 throw new IllegalArgumentException("Unknown package: " + packageName); 4591 } 4592 4593 final BasePermission bp = mSettings.mPermissions.get(name); 4594 if (bp == null) { 4595 throw new IllegalArgumentException("Unknown permission: " + name); 4596 } 4597 4598 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4599 4600 // If a permission review is required for legacy apps we represent 4601 // their permissions as always granted runtime ones since we need 4602 // to keep the review required permission flag per user while an 4603 // install permission's state is shared across all users. 4604 if (mPermissionReviewRequired 4605 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4606 && bp.isRuntime()) { 4607 return; 4608 } 4609 4610 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 4611 sb = (SettingBase) pkg.mExtras; 4612 if (sb == null) { 4613 throw new IllegalArgumentException("Unknown package: " + packageName); 4614 } 4615 4616 final PermissionsState permissionsState = sb.getPermissionsState(); 4617 4618 final int flags = permissionsState.getPermissionFlags(name, userId); 4619 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4620 throw new SecurityException("Cannot grant system fixed permission " 4621 + name + " for package " + packageName); 4622 } 4623 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4624 throw new SecurityException("Cannot grant policy fixed permission " 4625 + name + " for package " + packageName); 4626 } 4627 4628 if (bp.isDevelopment()) { 4629 // Development permissions must be handled specially, since they are not 4630 // normal runtime permissions. For now they apply to all users. 4631 if (permissionsState.grantInstallPermission(bp) != 4632 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4633 scheduleWriteSettingsLocked(); 4634 } 4635 return; 4636 } 4637 4638 final PackageSetting ps = mSettings.mPackages.get(packageName); 4639 if (ps.getInstantApp(userId) && !bp.isInstant()) { 4640 throw new SecurityException("Cannot grant non-ephemeral permission" 4641 + name + " for package " + packageName); 4642 } 4643 4644 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4645 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4646 return; 4647 } 4648 4649 final int result = permissionsState.grantRuntimePermission(bp, userId); 4650 switch (result) { 4651 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4652 return; 4653 } 4654 4655 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4656 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4657 mHandler.post(new Runnable() { 4658 @Override 4659 public void run() { 4660 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4661 } 4662 }); 4663 } 4664 break; 4665 } 4666 4667 if (bp.isRuntime()) { 4668 logPermissionGranted(mContext, name, packageName); 4669 } 4670 4671 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4672 4673 // Not critical if that is lost - app has to request again. 4674 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4675 } 4676 4677 // Only need to do this if user is initialized. Otherwise it's a new user 4678 // and there are no processes running as the user yet and there's no need 4679 // to make an expensive call to remount processes for the changed permissions. 4680 if (READ_EXTERNAL_STORAGE.equals(name) 4681 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4682 final long token = Binder.clearCallingIdentity(); 4683 try { 4684 if (sUserManager.isInitialized(userId)) { 4685 StorageManagerInternal storageManagerInternal = LocalServices.getService( 4686 StorageManagerInternal.class); 4687 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName); 4688 } 4689 } finally { 4690 Binder.restoreCallingIdentity(token); 4691 } 4692 } 4693 } 4694 4695 @Override 4696 public void revokeRuntimePermission(String packageName, String name, int userId) { 4697 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4698 } 4699 4700 private void revokeRuntimePermission(String packageName, String name, int userId, 4701 boolean overridePolicy) { 4702 if (!sUserManager.exists(userId)) { 4703 Log.e(TAG, "No such user:" + userId); 4704 return; 4705 } 4706 4707 mContext.enforceCallingOrSelfPermission( 4708 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4709 "revokeRuntimePermission"); 4710 4711 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4712 true /* requireFullPermission */, true /* checkShell */, 4713 "revokeRuntimePermission"); 4714 4715 final int appId; 4716 4717 synchronized (mPackages) { 4718 final PackageParser.Package pkg = mPackages.get(packageName); 4719 if (pkg == null) { 4720 throw new IllegalArgumentException("Unknown package: " + packageName); 4721 } 4722 4723 final BasePermission bp = mSettings.mPermissions.get(name); 4724 if (bp == null) { 4725 throw new IllegalArgumentException("Unknown permission: " + name); 4726 } 4727 4728 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4729 4730 // If a permission review is required for legacy apps we represent 4731 // their permissions as always granted runtime ones since we need 4732 // to keep the review required permission flag per user while an 4733 // install permission's state is shared across all users. 4734 if (mPermissionReviewRequired 4735 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4736 && bp.isRuntime()) { 4737 return; 4738 } 4739 4740 SettingBase sb = (SettingBase) pkg.mExtras; 4741 if (sb == null) { 4742 throw new IllegalArgumentException("Unknown package: " + packageName); 4743 } 4744 4745 final PermissionsState permissionsState = sb.getPermissionsState(); 4746 4747 final int flags = permissionsState.getPermissionFlags(name, userId); 4748 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4749 throw new SecurityException("Cannot revoke system fixed permission " 4750 + name + " for package " + packageName); 4751 } 4752 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4753 throw new SecurityException("Cannot revoke policy fixed permission " 4754 + name + " for package " + packageName); 4755 } 4756 4757 if (bp.isDevelopment()) { 4758 // Development permissions must be handled specially, since they are not 4759 // normal runtime permissions. For now they apply to all users. 4760 if (permissionsState.revokeInstallPermission(bp) != 4761 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4762 scheduleWriteSettingsLocked(); 4763 } 4764 return; 4765 } 4766 4767 if (permissionsState.revokeRuntimePermission(bp, userId) == 4768 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4769 return; 4770 } 4771 4772 if (bp.isRuntime()) { 4773 logPermissionRevoked(mContext, name, packageName); 4774 } 4775 4776 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4777 4778 // Critical, after this call app should never have the permission. 4779 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4780 4781 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4782 } 4783 4784 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4785 } 4786 4787 /** 4788 * Get the first event id for the permission. 4789 * 4790 * <p>There are four events for each permission: <ul> 4791 * <li>Request permission: first id + 0</li> 4792 * <li>Grant permission: first id + 1</li> 4793 * <li>Request for permission denied: first id + 2</li> 4794 * <li>Revoke permission: first id + 3</li> 4795 * </ul></p> 4796 * 4797 * @param name name of the permission 4798 * 4799 * @return The first event id for the permission 4800 */ 4801 private static int getBaseEventId(@NonNull String name) { 4802 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name); 4803 4804 if (eventIdIndex == -1) { 4805 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE 4806 || "user".equals(Build.TYPE)) { 4807 Log.i(TAG, "Unknown permission " + name); 4808 4809 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN; 4810 } else { 4811 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated. 4812 // 4813 // Also update 4814 // - EventLogger#ALL_DANGEROUS_PERMISSIONS 4815 // - metrics_constants.proto 4816 throw new IllegalStateException("Unknown permission " + name); 4817 } 4818 } 4819 4820 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4; 4821 } 4822 4823 /** 4824 * Log that a permission was revoked. 4825 * 4826 * @param context Context of the caller 4827 * @param name name of the permission 4828 * @param packageName package permission if for 4829 */ 4830 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name, 4831 @NonNull String packageName) { 4832 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName); 4833 } 4834 4835 /** 4836 * Log that a permission request was granted. 4837 * 4838 * @param context Context of the caller 4839 * @param name name of the permission 4840 * @param packageName package permission if for 4841 */ 4842 private static void logPermissionGranted(@NonNull Context context, @NonNull String name, 4843 @NonNull String packageName) { 4844 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName); 4845 } 4846 4847 @Override 4848 public void resetRuntimePermissions() { 4849 mContext.enforceCallingOrSelfPermission( 4850 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4851 "revokeRuntimePermission"); 4852 4853 int callingUid = Binder.getCallingUid(); 4854 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4855 mContext.enforceCallingOrSelfPermission( 4856 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4857 "resetRuntimePermissions"); 4858 } 4859 4860 synchronized (mPackages) { 4861 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4862 for (int userId : UserManagerService.getInstance().getUserIds()) { 4863 final int packageCount = mPackages.size(); 4864 for (int i = 0; i < packageCount; i++) { 4865 PackageParser.Package pkg = mPackages.valueAt(i); 4866 if (!(pkg.mExtras instanceof PackageSetting)) { 4867 continue; 4868 } 4869 PackageSetting ps = (PackageSetting) pkg.mExtras; 4870 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4871 } 4872 } 4873 } 4874 } 4875 4876 @Override 4877 public int getPermissionFlags(String name, String packageName, int userId) { 4878 if (!sUserManager.exists(userId)) { 4879 return 0; 4880 } 4881 4882 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4883 4884 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4885 true /* requireFullPermission */, false /* checkShell */, 4886 "getPermissionFlags"); 4887 4888 synchronized (mPackages) { 4889 final PackageParser.Package pkg = mPackages.get(packageName); 4890 if (pkg == null) { 4891 return 0; 4892 } 4893 4894 final BasePermission bp = mSettings.mPermissions.get(name); 4895 if (bp == null) { 4896 return 0; 4897 } 4898 4899 SettingBase sb = (SettingBase) pkg.mExtras; 4900 if (sb == null) { 4901 return 0; 4902 } 4903 4904 PermissionsState permissionsState = sb.getPermissionsState(); 4905 return permissionsState.getPermissionFlags(name, userId); 4906 } 4907 } 4908 4909 @Override 4910 public void updatePermissionFlags(String name, String packageName, int flagMask, 4911 int flagValues, int userId) { 4912 if (!sUserManager.exists(userId)) { 4913 return; 4914 } 4915 4916 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4917 4918 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4919 true /* requireFullPermission */, true /* checkShell */, 4920 "updatePermissionFlags"); 4921 4922 // Only the system can change these flags and nothing else. 4923 if (getCallingUid() != Process.SYSTEM_UID) { 4924 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4925 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4926 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4927 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4928 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4929 } 4930 4931 synchronized (mPackages) { 4932 final PackageParser.Package pkg = mPackages.get(packageName); 4933 if (pkg == null) { 4934 throw new IllegalArgumentException("Unknown package: " + packageName); 4935 } 4936 4937 final BasePermission bp = mSettings.mPermissions.get(name); 4938 if (bp == null) { 4939 throw new IllegalArgumentException("Unknown permission: " + name); 4940 } 4941 4942 SettingBase sb = (SettingBase) pkg.mExtras; 4943 if (sb == null) { 4944 throw new IllegalArgumentException("Unknown package: " + packageName); 4945 } 4946 4947 PermissionsState permissionsState = sb.getPermissionsState(); 4948 4949 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4950 4951 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4952 // Install and runtime permissions are stored in different places, 4953 // so figure out what permission changed and persist the change. 4954 if (permissionsState.getInstallPermissionState(name) != null) { 4955 scheduleWriteSettingsLocked(); 4956 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4957 || hadState) { 4958 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4959 } 4960 } 4961 } 4962 } 4963 4964 /** 4965 * Update the permission flags for all packages and runtime permissions of a user in order 4966 * to allow device or profile owner to remove POLICY_FIXED. 4967 */ 4968 @Override 4969 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4970 if (!sUserManager.exists(userId)) { 4971 return; 4972 } 4973 4974 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4975 4976 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4977 true /* requireFullPermission */, true /* checkShell */, 4978 "updatePermissionFlagsForAllApps"); 4979 4980 // Only the system can change system fixed flags. 4981 if (getCallingUid() != Process.SYSTEM_UID) { 4982 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4983 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4984 } 4985 4986 synchronized (mPackages) { 4987 boolean changed = false; 4988 final int packageCount = mPackages.size(); 4989 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4990 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4991 SettingBase sb = (SettingBase) pkg.mExtras; 4992 if (sb == null) { 4993 continue; 4994 } 4995 PermissionsState permissionsState = sb.getPermissionsState(); 4996 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4997 userId, flagMask, flagValues); 4998 } 4999 if (changed) { 5000 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 5001 } 5002 } 5003 } 5004 5005 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 5006 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 5007 != PackageManager.PERMISSION_GRANTED 5008 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 5009 != PackageManager.PERMISSION_GRANTED) { 5010 throw new SecurityException(message + " requires " 5011 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 5012 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 5013 } 5014 } 5015 5016 @Override 5017 public boolean shouldShowRequestPermissionRationale(String permissionName, 5018 String packageName, int userId) { 5019 if (UserHandle.getCallingUserId() != userId) { 5020 mContext.enforceCallingPermission( 5021 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5022 "canShowRequestPermissionRationale for user " + userId); 5023 } 5024 5025 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 5026 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 5027 return false; 5028 } 5029 5030 if (checkPermission(permissionName, packageName, userId) 5031 == PackageManager.PERMISSION_GRANTED) { 5032 return false; 5033 } 5034 5035 final int flags; 5036 5037 final long identity = Binder.clearCallingIdentity(); 5038 try { 5039 flags = getPermissionFlags(permissionName, 5040 packageName, userId); 5041 } finally { 5042 Binder.restoreCallingIdentity(identity); 5043 } 5044 5045 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 5046 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 5047 | PackageManager.FLAG_PERMISSION_USER_FIXED; 5048 5049 if ((flags & fixedFlags) != 0) { 5050 return false; 5051 } 5052 5053 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 5054 } 5055 5056 @Override 5057 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 5058 mContext.enforceCallingOrSelfPermission( 5059 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 5060 "addOnPermissionsChangeListener"); 5061 5062 synchronized (mPackages) { 5063 mOnPermissionChangeListeners.addListenerLocked(listener); 5064 } 5065 } 5066 5067 @Override 5068 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 5069 synchronized (mPackages) { 5070 mOnPermissionChangeListeners.removeListenerLocked(listener); 5071 } 5072 } 5073 5074 @Override 5075 public boolean isProtectedBroadcast(String actionName) { 5076 synchronized (mPackages) { 5077 if (mProtectedBroadcasts.contains(actionName)) { 5078 return true; 5079 } else if (actionName != null) { 5080 // TODO: remove these terrible hacks 5081 if (actionName.startsWith("android.net.netmon.lingerExpired") 5082 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 5083 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 5084 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 5085 return true; 5086 } 5087 } 5088 } 5089 return false; 5090 } 5091 5092 @Override 5093 public int checkSignatures(String pkg1, String pkg2) { 5094 synchronized (mPackages) { 5095 final PackageParser.Package p1 = mPackages.get(pkg1); 5096 final PackageParser.Package p2 = mPackages.get(pkg2); 5097 if (p1 == null || p1.mExtras == null 5098 || p2 == null || p2.mExtras == null) { 5099 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5100 } 5101 return compareSignatures(p1.mSignatures, p2.mSignatures); 5102 } 5103 } 5104 5105 @Override 5106 public int checkUidSignatures(int uid1, int uid2) { 5107 // Map to base uids. 5108 uid1 = UserHandle.getAppId(uid1); 5109 uid2 = UserHandle.getAppId(uid2); 5110 // reader 5111 synchronized (mPackages) { 5112 Signature[] s1; 5113 Signature[] s2; 5114 Object obj = mSettings.getUserIdLPr(uid1); 5115 if (obj != null) { 5116 if (obj instanceof SharedUserSetting) { 5117 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 5118 } else if (obj instanceof PackageSetting) { 5119 s1 = ((PackageSetting)obj).signatures.mSignatures; 5120 } else { 5121 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5122 } 5123 } else { 5124 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5125 } 5126 obj = mSettings.getUserIdLPr(uid2); 5127 if (obj != null) { 5128 if (obj instanceof SharedUserSetting) { 5129 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 5130 } else if (obj instanceof PackageSetting) { 5131 s2 = ((PackageSetting)obj).signatures.mSignatures; 5132 } else { 5133 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5134 } 5135 } else { 5136 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5137 } 5138 return compareSignatures(s1, s2); 5139 } 5140 } 5141 5142 /** 5143 * This method should typically only be used when granting or revoking 5144 * permissions, since the app may immediately restart after this call. 5145 * <p> 5146 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 5147 * guard your work against the app being relaunched. 5148 */ 5149 private void killUid(int appId, int userId, String reason) { 5150 final long identity = Binder.clearCallingIdentity(); 5151 try { 5152 IActivityManager am = ActivityManager.getService(); 5153 if (am != null) { 5154 try { 5155 am.killUid(appId, userId, reason); 5156 } catch (RemoteException e) { 5157 /* ignore - same process */ 5158 } 5159 } 5160 } finally { 5161 Binder.restoreCallingIdentity(identity); 5162 } 5163 } 5164 5165 /** 5166 * Compares two sets of signatures. Returns: 5167 * <br /> 5168 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 5169 * <br /> 5170 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 5171 * <br /> 5172 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 5173 * <br /> 5174 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 5175 * <br /> 5176 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 5177 */ 5178 static int compareSignatures(Signature[] s1, Signature[] s2) { 5179 if (s1 == null) { 5180 return s2 == null 5181 ? PackageManager.SIGNATURE_NEITHER_SIGNED 5182 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 5183 } 5184 5185 if (s2 == null) { 5186 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 5187 } 5188 5189 if (s1.length != s2.length) { 5190 return PackageManager.SIGNATURE_NO_MATCH; 5191 } 5192 5193 // Since both signature sets are of size 1, we can compare without HashSets. 5194 if (s1.length == 1) { 5195 return s1[0].equals(s2[0]) ? 5196 PackageManager.SIGNATURE_MATCH : 5197 PackageManager.SIGNATURE_NO_MATCH; 5198 } 5199 5200 ArraySet<Signature> set1 = new ArraySet<Signature>(); 5201 for (Signature sig : s1) { 5202 set1.add(sig); 5203 } 5204 ArraySet<Signature> set2 = new ArraySet<Signature>(); 5205 for (Signature sig : s2) { 5206 set2.add(sig); 5207 } 5208 // Make sure s2 contains all signatures in s1. 5209 if (set1.equals(set2)) { 5210 return PackageManager.SIGNATURE_MATCH; 5211 } 5212 return PackageManager.SIGNATURE_NO_MATCH; 5213 } 5214 5215 /** 5216 * If the database version for this type of package (internal storage or 5217 * external storage) is less than the version where package signatures 5218 * were updated, return true. 5219 */ 5220 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 5221 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 5222 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 5223 } 5224 5225 /** 5226 * Used for backward compatibility to make sure any packages with 5227 * certificate chains get upgraded to the new style. {@code existingSigs} 5228 * will be in the old format (since they were stored on disk from before the 5229 * system upgrade) and {@code scannedSigs} will be in the newer format. 5230 */ 5231 private int compareSignaturesCompat(PackageSignatures existingSigs, 5232 PackageParser.Package scannedPkg) { 5233 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 5234 return PackageManager.SIGNATURE_NO_MATCH; 5235 } 5236 5237 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 5238 for (Signature sig : existingSigs.mSignatures) { 5239 existingSet.add(sig); 5240 } 5241 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 5242 for (Signature sig : scannedPkg.mSignatures) { 5243 try { 5244 Signature[] chainSignatures = sig.getChainSignatures(); 5245 for (Signature chainSig : chainSignatures) { 5246 scannedCompatSet.add(chainSig); 5247 } 5248 } catch (CertificateEncodingException e) { 5249 scannedCompatSet.add(sig); 5250 } 5251 } 5252 /* 5253 * Make sure the expanded scanned set contains all signatures in the 5254 * existing one. 5255 */ 5256 if (scannedCompatSet.equals(existingSet)) { 5257 // Migrate the old signatures to the new scheme. 5258 existingSigs.assignSignatures(scannedPkg.mSignatures); 5259 // The new KeySets will be re-added later in the scanning process. 5260 synchronized (mPackages) { 5261 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 5262 } 5263 return PackageManager.SIGNATURE_MATCH; 5264 } 5265 return PackageManager.SIGNATURE_NO_MATCH; 5266 } 5267 5268 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 5269 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 5270 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 5271 } 5272 5273 private int compareSignaturesRecover(PackageSignatures existingSigs, 5274 PackageParser.Package scannedPkg) { 5275 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 5276 return PackageManager.SIGNATURE_NO_MATCH; 5277 } 5278 5279 String msg = null; 5280 try { 5281 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 5282 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 5283 + scannedPkg.packageName); 5284 return PackageManager.SIGNATURE_MATCH; 5285 } 5286 } catch (CertificateException e) { 5287 msg = e.getMessage(); 5288 } 5289 5290 logCriticalInfo(Log.INFO, 5291 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 5292 return PackageManager.SIGNATURE_NO_MATCH; 5293 } 5294 5295 @Override 5296 public List<String> getAllPackages() { 5297 synchronized (mPackages) { 5298 return new ArrayList<String>(mPackages.keySet()); 5299 } 5300 } 5301 5302 @Override 5303 public String[] getPackagesForUid(int uid) { 5304 final int userId = UserHandle.getUserId(uid); 5305 uid = UserHandle.getAppId(uid); 5306 // reader 5307 synchronized (mPackages) { 5308 Object obj = mSettings.getUserIdLPr(uid); 5309 if (obj instanceof SharedUserSetting) { 5310 final SharedUserSetting sus = (SharedUserSetting) obj; 5311 final int N = sus.packages.size(); 5312 String[] res = new String[N]; 5313 final Iterator<PackageSetting> it = sus.packages.iterator(); 5314 int i = 0; 5315 while (it.hasNext()) { 5316 PackageSetting ps = it.next(); 5317 if (ps.getInstalled(userId)) { 5318 res[i++] = ps.name; 5319 } else { 5320 res = ArrayUtils.removeElement(String.class, res, res[i]); 5321 } 5322 } 5323 return res; 5324 } else if (obj instanceof PackageSetting) { 5325 final PackageSetting ps = (PackageSetting) obj; 5326 if (ps.getInstalled(userId)) { 5327 return new String[]{ps.name}; 5328 } 5329 } 5330 } 5331 return null; 5332 } 5333 5334 @Override 5335 public String getNameForUid(int uid) { 5336 // reader 5337 synchronized (mPackages) { 5338 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5339 if (obj instanceof SharedUserSetting) { 5340 final SharedUserSetting sus = (SharedUserSetting) obj; 5341 return sus.name + ":" + sus.userId; 5342 } else if (obj instanceof PackageSetting) { 5343 final PackageSetting ps = (PackageSetting) obj; 5344 return ps.name; 5345 } 5346 } 5347 return null; 5348 } 5349 5350 @Override 5351 public int getUidForSharedUser(String sharedUserName) { 5352 if(sharedUserName == null) { 5353 return -1; 5354 } 5355 // reader 5356 synchronized (mPackages) { 5357 SharedUserSetting suid; 5358 try { 5359 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 5360 if (suid != null) { 5361 return suid.userId; 5362 } 5363 } catch (PackageManagerException ignore) { 5364 // can't happen, but, still need to catch it 5365 } 5366 return -1; 5367 } 5368 } 5369 5370 @Override 5371 public int getFlagsForUid(int uid) { 5372 synchronized (mPackages) { 5373 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5374 if (obj instanceof SharedUserSetting) { 5375 final SharedUserSetting sus = (SharedUserSetting) obj; 5376 return sus.pkgFlags; 5377 } else if (obj instanceof PackageSetting) { 5378 final PackageSetting ps = (PackageSetting) obj; 5379 return ps.pkgFlags; 5380 } 5381 } 5382 return 0; 5383 } 5384 5385 @Override 5386 public int getPrivateFlagsForUid(int uid) { 5387 synchronized (mPackages) { 5388 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5389 if (obj instanceof SharedUserSetting) { 5390 final SharedUserSetting sus = (SharedUserSetting) obj; 5391 return sus.pkgPrivateFlags; 5392 } else if (obj instanceof PackageSetting) { 5393 final PackageSetting ps = (PackageSetting) obj; 5394 return ps.pkgPrivateFlags; 5395 } 5396 } 5397 return 0; 5398 } 5399 5400 @Override 5401 public boolean isUidPrivileged(int uid) { 5402 uid = UserHandle.getAppId(uid); 5403 // reader 5404 synchronized (mPackages) { 5405 Object obj = mSettings.getUserIdLPr(uid); 5406 if (obj instanceof SharedUserSetting) { 5407 final SharedUserSetting sus = (SharedUserSetting) obj; 5408 final Iterator<PackageSetting> it = sus.packages.iterator(); 5409 while (it.hasNext()) { 5410 if (it.next().isPrivileged()) { 5411 return true; 5412 } 5413 } 5414 } else if (obj instanceof PackageSetting) { 5415 final PackageSetting ps = (PackageSetting) obj; 5416 return ps.isPrivileged(); 5417 } 5418 } 5419 return false; 5420 } 5421 5422 @Override 5423 public String[] getAppOpPermissionPackages(String permissionName) { 5424 synchronized (mPackages) { 5425 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 5426 if (pkgs == null) { 5427 return null; 5428 } 5429 return pkgs.toArray(new String[pkgs.size()]); 5430 } 5431 } 5432 5433 @Override 5434 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 5435 int flags, int userId) { 5436 try { 5437 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 5438 5439 if (!sUserManager.exists(userId)) return null; 5440 flags = updateFlagsForResolve(flags, userId, intent); 5441 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5442 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 5443 5444 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5445 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 5446 flags, userId); 5447 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5448 5449 final ResolveInfo bestChoice = 5450 chooseBestActivity(intent, resolvedType, flags, query, userId); 5451 return bestChoice; 5452 } finally { 5453 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5454 } 5455 } 5456 5457 @Override 5458 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) { 5459 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) { 5460 throw new SecurityException( 5461 "findPersistentPreferredActivity can only be run by the system"); 5462 } 5463 if (!sUserManager.exists(userId)) { 5464 return null; 5465 } 5466 intent = updateIntentForResolve(intent); 5467 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver()); 5468 final int flags = updateFlagsForResolve(0, userId, intent); 5469 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5470 userId); 5471 synchronized (mPackages) { 5472 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false, 5473 userId); 5474 } 5475 } 5476 5477 @Override 5478 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 5479 IntentFilter filter, int match, ComponentName activity) { 5480 final int userId = UserHandle.getCallingUserId(); 5481 if (DEBUG_PREFERRED) { 5482 Log.v(TAG, "setLastChosenActivity intent=" + intent 5483 + " resolvedType=" + resolvedType 5484 + " flags=" + flags 5485 + " filter=" + filter 5486 + " match=" + match 5487 + " activity=" + activity); 5488 filter.dump(new PrintStreamPrinter(System.out), " "); 5489 } 5490 intent.setComponent(null); 5491 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5492 userId); 5493 // Find any earlier preferred or last chosen entries and nuke them 5494 findPreferredActivity(intent, resolvedType, 5495 flags, query, 0, false, true, false, userId); 5496 // Add the new activity as the last chosen for this filter 5497 addPreferredActivityInternal(filter, match, null, activity, false, userId, 5498 "Setting last chosen"); 5499 } 5500 5501 @Override 5502 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 5503 final int userId = UserHandle.getCallingUserId(); 5504 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 5505 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5506 userId); 5507 return findPreferredActivity(intent, resolvedType, flags, query, 0, 5508 false, false, false, userId); 5509 } 5510 5511 private boolean isEphemeralDisabled() { 5512 // ephemeral apps have been disabled across the board 5513 if (DISABLE_EPHEMERAL_APPS) { 5514 return true; 5515 } 5516 // system isn't up yet; can't read settings, so, assume no ephemeral apps 5517 if (!mSystemReady) { 5518 return true; 5519 } 5520 // we can't get a content resolver until the system is ready; these checks must happen last 5521 final ContentResolver resolver = mContext.getContentResolver(); 5522 if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) { 5523 return true; 5524 } 5525 return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0; 5526 } 5527 5528 private boolean isEphemeralAllowed( 5529 Intent intent, List<ResolveInfo> resolvedActivities, int userId, 5530 boolean skipPackageCheck) { 5531 // Short circuit and return early if possible. 5532 if (isEphemeralDisabled()) { 5533 return false; 5534 } 5535 final int callingUser = UserHandle.getCallingUserId(); 5536 if (callingUser != UserHandle.USER_SYSTEM) { 5537 return false; 5538 } 5539 if (mEphemeralResolverConnection == null) { 5540 return false; 5541 } 5542 if (mEphemeralInstallerComponent == null) { 5543 return false; 5544 } 5545 if (intent.getComponent() != null) { 5546 return false; 5547 } 5548 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) { 5549 return false; 5550 } 5551 if (!skipPackageCheck && intent.getPackage() != null) { 5552 return false; 5553 } 5554 final boolean isWebUri = hasWebURI(intent); 5555 if (!isWebUri || intent.getData().getHost() == null) { 5556 return false; 5557 } 5558 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 5559 synchronized (mPackages) { 5560 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); 5561 for (int n = 0; n < count; n++) { 5562 ResolveInfo info = resolvedActivities.get(n); 5563 String packageName = info.activityInfo.packageName; 5564 PackageSetting ps = mSettings.mPackages.get(packageName); 5565 if (ps != null) { 5566 // Try to get the status from User settings first 5567 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5568 int status = (int) (packedStatus >> 32); 5569 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 5570 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5571 if (DEBUG_EPHEMERAL) { 5572 Slog.v(TAG, "DENY ephemeral apps;" 5573 + " pkg: " + packageName + ", status: " + status); 5574 } 5575 return false; 5576 } 5577 } 5578 } 5579 } 5580 // We've exhausted all ways to deny ephemeral application; let the system look for them. 5581 return true; 5582 } 5583 5584 private void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj, 5585 Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage, 5586 int userId) { 5587 final Message msg = mHandler.obtainMessage(EPHEMERAL_RESOLUTION_PHASE_TWO, 5588 new EphemeralRequest(responseObj, origIntent, resolvedType, launchIntent, 5589 callingPackage, userId)); 5590 mHandler.sendMessage(msg); 5591 } 5592 5593 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 5594 int flags, List<ResolveInfo> query, int userId) { 5595 if (query != null) { 5596 final int N = query.size(); 5597 if (N == 1) { 5598 return query.get(0); 5599 } else if (N > 1) { 5600 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 5601 // If there is more than one activity with the same priority, 5602 // then let the user decide between them. 5603 ResolveInfo r0 = query.get(0); 5604 ResolveInfo r1 = query.get(1); 5605 if (DEBUG_INTENT_MATCHING || debug) { 5606 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 5607 + r1.activityInfo.name + "=" + r1.priority); 5608 } 5609 // If the first activity has a higher priority, or a different 5610 // default, then it is always desirable to pick it. 5611 if (r0.priority != r1.priority 5612 || r0.preferredOrder != r1.preferredOrder 5613 || r0.isDefault != r1.isDefault) { 5614 return query.get(0); 5615 } 5616 // If we have saved a preference for a preferred activity for 5617 // this Intent, use that. 5618 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 5619 flags, query, r0.priority, true, false, debug, userId); 5620 if (ri != null) { 5621 return ri; 5622 } 5623 ri = new ResolveInfo(mResolveInfo); 5624 ri.activityInfo = new ActivityInfo(ri.activityInfo); 5625 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 5626 // If all of the options come from the same package, show the application's 5627 // label and icon instead of the generic resolver's. 5628 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 5629 // and then throw away the ResolveInfo itself, meaning that the caller loses 5630 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 5631 // a fallback for this case; we only set the target package's resources on 5632 // the ResolveInfo, not the ActivityInfo. 5633 final String intentPackage = intent.getPackage(); 5634 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 5635 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 5636 ri.resolvePackageName = intentPackage; 5637 if (userNeedsBadging(userId)) { 5638 ri.noResourceId = true; 5639 } else { 5640 ri.icon = appi.icon; 5641 } 5642 ri.iconResourceId = appi.icon; 5643 ri.labelRes = appi.labelRes; 5644 } 5645 ri.activityInfo.applicationInfo = new ApplicationInfo( 5646 ri.activityInfo.applicationInfo); 5647 if (userId != 0) { 5648 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 5649 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 5650 } 5651 // Make sure that the resolver is displayable in car mode 5652 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 5653 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 5654 return ri; 5655 } 5656 } 5657 return null; 5658 } 5659 5660 /** 5661 * Return true if the given list is not empty and all of its contents have 5662 * an activityInfo with the given package name. 5663 */ 5664 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 5665 if (ArrayUtils.isEmpty(list)) { 5666 return false; 5667 } 5668 for (int i = 0, N = list.size(); i < N; i++) { 5669 final ResolveInfo ri = list.get(i); 5670 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 5671 if (ai == null || !packageName.equals(ai.packageName)) { 5672 return false; 5673 } 5674 } 5675 return true; 5676 } 5677 5678 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 5679 int flags, List<ResolveInfo> query, boolean debug, int userId) { 5680 final int N = query.size(); 5681 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 5682 .get(userId); 5683 // Get the list of persistent preferred activities that handle the intent 5684 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 5685 List<PersistentPreferredActivity> pprefs = ppir != null 5686 ? ppir.queryIntent(intent, resolvedType, 5687 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5688 userId) 5689 : null; 5690 if (pprefs != null && pprefs.size() > 0) { 5691 final int M = pprefs.size(); 5692 for (int i=0; i<M; i++) { 5693 final PersistentPreferredActivity ppa = pprefs.get(i); 5694 if (DEBUG_PREFERRED || debug) { 5695 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 5696 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 5697 + "\n component=" + ppa.mComponent); 5698 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5699 } 5700 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 5701 flags | MATCH_DISABLED_COMPONENTS, userId); 5702 if (DEBUG_PREFERRED || debug) { 5703 Slog.v(TAG, "Found persistent preferred activity:"); 5704 if (ai != null) { 5705 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5706 } else { 5707 Slog.v(TAG, " null"); 5708 } 5709 } 5710 if (ai == null) { 5711 // This previously registered persistent preferred activity 5712 // component is no longer known. Ignore it and do NOT remove it. 5713 continue; 5714 } 5715 for (int j=0; j<N; j++) { 5716 final ResolveInfo ri = query.get(j); 5717 if (!ri.activityInfo.applicationInfo.packageName 5718 .equals(ai.applicationInfo.packageName)) { 5719 continue; 5720 } 5721 if (!ri.activityInfo.name.equals(ai.name)) { 5722 continue; 5723 } 5724 // Found a persistent preference that can handle the intent. 5725 if (DEBUG_PREFERRED || debug) { 5726 Slog.v(TAG, "Returning persistent preferred activity: " + 5727 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5728 } 5729 return ri; 5730 } 5731 } 5732 } 5733 return null; 5734 } 5735 5736 // TODO: handle preferred activities missing while user has amnesia 5737 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5738 List<ResolveInfo> query, int priority, boolean always, 5739 boolean removeMatches, boolean debug, int userId) { 5740 if (!sUserManager.exists(userId)) return null; 5741 flags = updateFlagsForResolve(flags, userId, intent); 5742 intent = updateIntentForResolve(intent); 5743 // writer 5744 synchronized (mPackages) { 5745 // Try to find a matching persistent preferred activity. 5746 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5747 debug, userId); 5748 5749 // If a persistent preferred activity matched, use it. 5750 if (pri != null) { 5751 return pri; 5752 } 5753 5754 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5755 // Get the list of preferred activities that handle the intent 5756 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5757 List<PreferredActivity> prefs = pir != null 5758 ? pir.queryIntent(intent, resolvedType, 5759 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5760 userId) 5761 : null; 5762 if (prefs != null && prefs.size() > 0) { 5763 boolean changed = false; 5764 try { 5765 // First figure out how good the original match set is. 5766 // We will only allow preferred activities that came 5767 // from the same match quality. 5768 int match = 0; 5769 5770 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5771 5772 final int N = query.size(); 5773 for (int j=0; j<N; j++) { 5774 final ResolveInfo ri = query.get(j); 5775 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 5776 + ": 0x" + Integer.toHexString(match)); 5777 if (ri.match > match) { 5778 match = ri.match; 5779 } 5780 } 5781 5782 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 5783 + Integer.toHexString(match)); 5784 5785 match &= IntentFilter.MATCH_CATEGORY_MASK; 5786 final int M = prefs.size(); 5787 for (int i=0; i<M; i++) { 5788 final PreferredActivity pa = prefs.get(i); 5789 if (DEBUG_PREFERRED || debug) { 5790 Slog.v(TAG, "Checking PreferredActivity ds=" 5791 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5792 + "\n component=" + pa.mPref.mComponent); 5793 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5794 } 5795 if (pa.mPref.mMatch != match) { 5796 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5797 + Integer.toHexString(pa.mPref.mMatch)); 5798 continue; 5799 } 5800 // If it's not an "always" type preferred activity and that's what we're 5801 // looking for, skip it. 5802 if (always && !pa.mPref.mAlways) { 5803 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5804 continue; 5805 } 5806 final ActivityInfo ai = getActivityInfo( 5807 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5808 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5809 userId); 5810 if (DEBUG_PREFERRED || debug) { 5811 Slog.v(TAG, "Found preferred activity:"); 5812 if (ai != null) { 5813 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5814 } else { 5815 Slog.v(TAG, " null"); 5816 } 5817 } 5818 if (ai == null) { 5819 // This previously registered preferred activity 5820 // component is no longer known. Most likely an update 5821 // to the app was installed and in the new version this 5822 // component no longer exists. Clean it up by removing 5823 // it from the preferred activities list, and skip it. 5824 Slog.w(TAG, "Removing dangling preferred activity: " 5825 + pa.mPref.mComponent); 5826 pir.removeFilter(pa); 5827 changed = true; 5828 continue; 5829 } 5830 for (int j=0; j<N; j++) { 5831 final ResolveInfo ri = query.get(j); 5832 if (!ri.activityInfo.applicationInfo.packageName 5833 .equals(ai.applicationInfo.packageName)) { 5834 continue; 5835 } 5836 if (!ri.activityInfo.name.equals(ai.name)) { 5837 continue; 5838 } 5839 5840 if (removeMatches) { 5841 pir.removeFilter(pa); 5842 changed = true; 5843 if (DEBUG_PREFERRED) { 5844 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 5845 } 5846 break; 5847 } 5848 5849 // Okay we found a previously set preferred or last chosen app. 5850 // If the result set is different from when this 5851 // was created, we need to clear it and re-ask the 5852 // user their preference, if we're looking for an "always" type entry. 5853 if (always && !pa.mPref.sameSet(query)) { 5854 Slog.i(TAG, "Result set changed, dropping preferred activity for " 5855 + intent + " type " + resolvedType); 5856 if (DEBUG_PREFERRED) { 5857 Slog.v(TAG, "Removing preferred activity since set changed " 5858 + pa.mPref.mComponent); 5859 } 5860 pir.removeFilter(pa); 5861 // Re-add the filter as a "last chosen" entry (!always) 5862 PreferredActivity lastChosen = new PreferredActivity( 5863 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 5864 pir.addFilter(lastChosen); 5865 changed = true; 5866 return null; 5867 } 5868 5869 // Yay! Either the set matched or we're looking for the last chosen 5870 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5871 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5872 return ri; 5873 } 5874 } 5875 } finally { 5876 if (changed) { 5877 if (DEBUG_PREFERRED) { 5878 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5879 } 5880 scheduleWritePackageRestrictionsLocked(userId); 5881 } 5882 } 5883 } 5884 } 5885 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5886 return null; 5887 } 5888 5889 /* 5890 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5891 */ 5892 @Override 5893 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5894 int targetUserId) { 5895 mContext.enforceCallingOrSelfPermission( 5896 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5897 List<CrossProfileIntentFilter> matches = 5898 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5899 if (matches != null) { 5900 int size = matches.size(); 5901 for (int i = 0; i < size; i++) { 5902 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5903 } 5904 } 5905 if (hasWebURI(intent)) { 5906 // cross-profile app linking works only towards the parent. 5907 final UserInfo parent = getProfileParent(sourceUserId); 5908 synchronized(mPackages) { 5909 int flags = updateFlagsForResolve(0, parent.id, intent); 5910 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5911 intent, resolvedType, flags, sourceUserId, parent.id); 5912 return xpDomainInfo != null; 5913 } 5914 } 5915 return false; 5916 } 5917 5918 private UserInfo getProfileParent(int userId) { 5919 final long identity = Binder.clearCallingIdentity(); 5920 try { 5921 return sUserManager.getProfileParent(userId); 5922 } finally { 5923 Binder.restoreCallingIdentity(identity); 5924 } 5925 } 5926 5927 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5928 String resolvedType, int userId) { 5929 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5930 if (resolver != null) { 5931 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId); 5932 } 5933 return null; 5934 } 5935 5936 @Override 5937 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5938 String resolvedType, int flags, int userId) { 5939 try { 5940 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5941 5942 return new ParceledListSlice<>( 5943 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5944 } finally { 5945 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5946 } 5947 } 5948 5949 /** 5950 * Returns the package name of the calling Uid if it's an instant app. If it isn't 5951 * instant, returns {@code null}. 5952 */ 5953 private String getInstantAppPackageName(int callingUid) { 5954 final int appId = UserHandle.getAppId(callingUid); 5955 synchronized (mPackages) { 5956 final Object obj = mSettings.getUserIdLPr(appId); 5957 if (obj instanceof PackageSetting) { 5958 final PackageSetting ps = (PackageSetting) obj; 5959 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid)); 5960 return isInstantApp ? ps.pkg.packageName : null; 5961 } 5962 } 5963 return null; 5964 } 5965 5966 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5967 String resolvedType, int flags, int userId) { 5968 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5969 final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid()); 5970 flags = updateFlagsForResolve(flags, userId, intent); 5971 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5972 false /* requireFullPermission */, false /* checkShell */, 5973 "query intent activities"); 5974 ComponentName comp = intent.getComponent(); 5975 if (comp == null) { 5976 if (intent.getSelector() != null) { 5977 intent = intent.getSelector(); 5978 comp = intent.getComponent(); 5979 } 5980 } 5981 5982 if (comp != null) { 5983 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5984 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5985 if (ai != null) { 5986 // When specifying an explicit component, we prevent the activity from being 5987 // used when either 1) the calling package is normal and the activity is within 5988 // an ephemeral application or 2) the calling package is ephemeral and the 5989 // activity is not visible to ephemeral applications. 5990 boolean matchEphemeral = 5991 (flags & PackageManager.MATCH_INSTANT) != 0; 5992 boolean ephemeralVisibleOnly = 5993 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; 5994 boolean blockResolution = 5995 (!matchEphemeral && instantAppPkgName == null 5996 && (ai.applicationInfo.privateFlags 5997 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0) 5998 || (ephemeralVisibleOnly && instantAppPkgName != null 5999 && (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0); 6000 if (!blockResolution) { 6001 final ResolveInfo ri = new ResolveInfo(); 6002 ri.activityInfo = ai; 6003 list.add(ri); 6004 } 6005 } 6006 return list; 6007 } 6008 6009 // reader 6010 boolean sortResult = false; 6011 boolean addEphemeral = false; 6012 List<ResolveInfo> result; 6013 final String pkgName = intent.getPackage(); 6014 synchronized (mPackages) { 6015 if (pkgName == null) { 6016 List<CrossProfileIntentFilter> matchingFilters = 6017 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 6018 // Check for results that need to skip the current profile. 6019 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 6020 resolvedType, flags, userId); 6021 if (xpResolveInfo != null) { 6022 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); 6023 xpResult.add(xpResolveInfo); 6024 return filterForEphemeral( 6025 filterIfNotSystemUser(xpResult, userId), instantAppPkgName); 6026 } 6027 6028 // Check for results in the current profile. 6029 result = filterIfNotSystemUser(mActivities.queryIntent( 6030 intent, resolvedType, flags, userId), userId); 6031 addEphemeral = 6032 isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); 6033 6034 // Check for cross profile results. 6035 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 6036 xpResolveInfo = queryCrossProfileIntents( 6037 matchingFilters, intent, resolvedType, flags, userId, 6038 hasNonNegativePriorityResult); 6039 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 6040 boolean isVisibleToUser = filterIfNotSystemUser( 6041 Collections.singletonList(xpResolveInfo), userId).size() > 0; 6042 if (isVisibleToUser) { 6043 result.add(xpResolveInfo); 6044 sortResult = true; 6045 } 6046 } 6047 if (hasWebURI(intent)) { 6048 CrossProfileDomainInfo xpDomainInfo = null; 6049 final UserInfo parent = getProfileParent(userId); 6050 if (parent != null) { 6051 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 6052 flags, userId, parent.id); 6053 } 6054 if (xpDomainInfo != null) { 6055 if (xpResolveInfo != null) { 6056 // If we didn't remove it, the cross-profile ResolveInfo would be twice 6057 // in the result. 6058 result.remove(xpResolveInfo); 6059 } 6060 if (result.size() == 0 && !addEphemeral) { 6061 // No result in current profile, but found candidate in parent user. 6062 // And we are not going to add emphemeral app, so we can return the 6063 // result straight away. 6064 result.add(xpDomainInfo.resolveInfo); 6065 return filterForEphemeral(result, instantAppPkgName); 6066 } 6067 } else if (result.size() <= 1 && !addEphemeral) { 6068 // No result in parent user and <= 1 result in current profile, and we 6069 // are not going to add emphemeral app, so we can return the result without 6070 // further processing. 6071 return filterForEphemeral(result, instantAppPkgName); 6072 } 6073 // We have more than one candidate (combining results from current and parent 6074 // profile), so we need filtering and sorting. 6075 result = filterCandidatesWithDomainPreferredActivitiesLPr( 6076 intent, flags, result, xpDomainInfo, userId); 6077 sortResult = true; 6078 } 6079 } else { 6080 final PackageParser.Package pkg = mPackages.get(pkgName); 6081 if (pkg != null) { 6082 result = filterForEphemeral(filterIfNotSystemUser( 6083 mActivities.queryIntentForPackage( 6084 intent, resolvedType, flags, pkg.activities, userId), 6085 userId), instantAppPkgName); 6086 } else { 6087 // the caller wants to resolve for a particular package; however, there 6088 // were no installed results, so, try to find an ephemeral result 6089 addEphemeral = isEphemeralAllowed( 6090 intent, null /*result*/, userId, true /*skipPackageCheck*/); 6091 result = new ArrayList<ResolveInfo>(); 6092 } 6093 } 6094 } 6095 if (addEphemeral) { 6096 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 6097 final EphemeralRequest requestObject = new EphemeralRequest( 6098 null /*responseObj*/, intent /*origIntent*/, resolvedType, 6099 null /*launchIntent*/, null /*callingPackage*/, userId); 6100 final EphemeralResponse intentInfo = EphemeralResolver.doEphemeralResolutionPhaseOne( 6101 mContext, mEphemeralResolverConnection, requestObject); 6102 if (intentInfo != null) { 6103 if (DEBUG_EPHEMERAL) { 6104 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 6105 } 6106 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo); 6107 ephemeralInstaller.ephemeralResponse = intentInfo; 6108 // make sure this resolver is the default 6109 ephemeralInstaller.isDefault = true; 6110 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 6111 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 6112 // add a non-generic filter 6113 ephemeralInstaller.filter = new IntentFilter(intent.getAction()); 6114 ephemeralInstaller.filter.addDataPath( 6115 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL); 6116 result.add(ephemeralInstaller); 6117 } 6118 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6119 } 6120 if (sortResult) { 6121 Collections.sort(result, mResolvePrioritySorter); 6122 } 6123 return filterForEphemeral(result, instantAppPkgName); 6124 } 6125 6126 private static class CrossProfileDomainInfo { 6127 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 6128 ResolveInfo resolveInfo; 6129 /* Best domain verification status of the activities found in the other profile */ 6130 int bestDomainVerificationStatus; 6131 } 6132 6133 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 6134 String resolvedType, int flags, int sourceUserId, int parentUserId) { 6135 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 6136 sourceUserId)) { 6137 return null; 6138 } 6139 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 6140 resolvedType, flags, parentUserId); 6141 6142 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 6143 return null; 6144 } 6145 CrossProfileDomainInfo result = null; 6146 int size = resultTargetUser.size(); 6147 for (int i = 0; i < size; i++) { 6148 ResolveInfo riTargetUser = resultTargetUser.get(i); 6149 // Intent filter verification is only for filters that specify a host. So don't return 6150 // those that handle all web uris. 6151 if (riTargetUser.handleAllWebDataURI) { 6152 continue; 6153 } 6154 String packageName = riTargetUser.activityInfo.packageName; 6155 PackageSetting ps = mSettings.mPackages.get(packageName); 6156 if (ps == null) { 6157 continue; 6158 } 6159 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 6160 int status = (int)(verificationState >> 32); 6161 if (result == null) { 6162 result = new CrossProfileDomainInfo(); 6163 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 6164 sourceUserId, parentUserId); 6165 result.bestDomainVerificationStatus = status; 6166 } else { 6167 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 6168 result.bestDomainVerificationStatus); 6169 } 6170 } 6171 // Don't consider matches with status NEVER across profiles. 6172 if (result != null && result.bestDomainVerificationStatus 6173 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6174 return null; 6175 } 6176 return result; 6177 } 6178 6179 /** 6180 * Verification statuses are ordered from the worse to the best, except for 6181 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 6182 */ 6183 private int bestDomainVerificationStatus(int status1, int status2) { 6184 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6185 return status2; 6186 } 6187 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6188 return status1; 6189 } 6190 return (int) MathUtils.max(status1, status2); 6191 } 6192 6193 private boolean isUserEnabled(int userId) { 6194 long callingId = Binder.clearCallingIdentity(); 6195 try { 6196 UserInfo userInfo = sUserManager.getUserInfo(userId); 6197 return userInfo != null && userInfo.isEnabled(); 6198 } finally { 6199 Binder.restoreCallingIdentity(callingId); 6200 } 6201 } 6202 6203 /** 6204 * Filter out activities with systemUserOnly flag set, when current user is not System. 6205 * 6206 * @return filtered list 6207 */ 6208 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 6209 if (userId == UserHandle.USER_SYSTEM) { 6210 return resolveInfos; 6211 } 6212 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 6213 ResolveInfo info = resolveInfos.get(i); 6214 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 6215 resolveInfos.remove(i); 6216 } 6217 } 6218 return resolveInfos; 6219 } 6220 6221 /** 6222 * Filters out ephemeral activities. 6223 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the 6224 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned. 6225 * 6226 * @param resolveInfos The pre-filtered list of resolved activities 6227 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering 6228 * is performed. 6229 * @return A filtered list of resolved activities. 6230 */ 6231 private List<ResolveInfo> filterForEphemeral(List<ResolveInfo> resolveInfos, 6232 String ephemeralPkgName) { 6233 if (ephemeralPkgName == null) { 6234 return resolveInfos; 6235 } 6236 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 6237 ResolveInfo info = resolveInfos.get(i); 6238 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp(); 6239 // allow activities that are defined in the provided package 6240 if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) { 6241 continue; 6242 } 6243 // allow activities that have been explicitly exposed to ephemeral apps 6244 if (!isEphemeralApp 6245 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) { 6246 continue; 6247 } 6248 resolveInfos.remove(i); 6249 } 6250 return resolveInfos; 6251 } 6252 6253 /** 6254 * @param resolveInfos list of resolve infos in descending priority order 6255 * @return if the list contains a resolve info with non-negative priority 6256 */ 6257 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 6258 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 6259 } 6260 6261 private static boolean hasWebURI(Intent intent) { 6262 if (intent.getData() == null) { 6263 return false; 6264 } 6265 final String scheme = intent.getScheme(); 6266 if (TextUtils.isEmpty(scheme)) { 6267 return false; 6268 } 6269 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 6270 } 6271 6272 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 6273 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 6274 int userId) { 6275 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 6276 6277 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 6278 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 6279 candidates.size()); 6280 } 6281 6282 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 6283 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 6284 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 6285 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 6286 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 6287 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 6288 6289 synchronized (mPackages) { 6290 final int count = candidates.size(); 6291 // First, try to use linked apps. Partition the candidates into four lists: 6292 // one for the final results, one for the "do not use ever", one for "undefined status" 6293 // and finally one for "browser app type". 6294 for (int n=0; n<count; n++) { 6295 ResolveInfo info = candidates.get(n); 6296 String packageName = info.activityInfo.packageName; 6297 PackageSetting ps = mSettings.mPackages.get(packageName); 6298 if (ps != null) { 6299 // Add to the special match all list (Browser use case) 6300 if (info.handleAllWebDataURI) { 6301 matchAllList.add(info); 6302 continue; 6303 } 6304 // Try to get the status from User settings first 6305 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 6306 int status = (int)(packedStatus >> 32); 6307 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 6308 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 6309 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6310 Slog.i(TAG, " + always: " + info.activityInfo.packageName 6311 + " : linkgen=" + linkGeneration); 6312 } 6313 // Use link-enabled generation as preferredOrder, i.e. 6314 // prefer newly-enabled over earlier-enabled. 6315 info.preferredOrder = linkGeneration; 6316 alwaysList.add(info); 6317 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6318 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6319 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 6320 } 6321 neverList.add(info); 6322 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 6323 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6324 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 6325 } 6326 alwaysAskList.add(info); 6327 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 6328 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 6329 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6330 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 6331 } 6332 undefinedList.add(info); 6333 } 6334 } 6335 } 6336 6337 // We'll want to include browser possibilities in a few cases 6338 boolean includeBrowser = false; 6339 6340 // First try to add the "always" resolution(s) for the current user, if any 6341 if (alwaysList.size() > 0) { 6342 result.addAll(alwaysList); 6343 } else { 6344 // Add all undefined apps as we want them to appear in the disambiguation dialog. 6345 result.addAll(undefinedList); 6346 // Maybe add one for the other profile. 6347 if (xpDomainInfo != null && ( 6348 xpDomainInfo.bestDomainVerificationStatus 6349 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 6350 result.add(xpDomainInfo.resolveInfo); 6351 } 6352 includeBrowser = true; 6353 } 6354 6355 // The presence of any 'always ask' alternatives means we'll also offer browsers. 6356 // If there were 'always' entries their preferred order has been set, so we also 6357 // back that off to make the alternatives equivalent 6358 if (alwaysAskList.size() > 0) { 6359 for (ResolveInfo i : result) { 6360 i.preferredOrder = 0; 6361 } 6362 result.addAll(alwaysAskList); 6363 includeBrowser = true; 6364 } 6365 6366 if (includeBrowser) { 6367 // Also add browsers (all of them or only the default one) 6368 if (DEBUG_DOMAIN_VERIFICATION) { 6369 Slog.v(TAG, " ...including browsers in candidate set"); 6370 } 6371 if ((matchFlags & MATCH_ALL) != 0) { 6372 result.addAll(matchAllList); 6373 } else { 6374 // Browser/generic handling case. If there's a default browser, go straight 6375 // to that (but only if there is no other higher-priority match). 6376 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 6377 int maxMatchPrio = 0; 6378 ResolveInfo defaultBrowserMatch = null; 6379 final int numCandidates = matchAllList.size(); 6380 for (int n = 0; n < numCandidates; n++) { 6381 ResolveInfo info = matchAllList.get(n); 6382 // track the highest overall match priority... 6383 if (info.priority > maxMatchPrio) { 6384 maxMatchPrio = info.priority; 6385 } 6386 // ...and the highest-priority default browser match 6387 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 6388 if (defaultBrowserMatch == null 6389 || (defaultBrowserMatch.priority < info.priority)) { 6390 if (debug) { 6391 Slog.v(TAG, "Considering default browser match " + info); 6392 } 6393 defaultBrowserMatch = info; 6394 } 6395 } 6396 } 6397 if (defaultBrowserMatch != null 6398 && defaultBrowserMatch.priority >= maxMatchPrio 6399 && !TextUtils.isEmpty(defaultBrowserPackageName)) 6400 { 6401 if (debug) { 6402 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 6403 } 6404 result.add(defaultBrowserMatch); 6405 } else { 6406 result.addAll(matchAllList); 6407 } 6408 } 6409 6410 // If there is nothing selected, add all candidates and remove the ones that the user 6411 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 6412 if (result.size() == 0) { 6413 result.addAll(candidates); 6414 result.removeAll(neverList); 6415 } 6416 } 6417 } 6418 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 6419 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 6420 result.size()); 6421 for (ResolveInfo info : result) { 6422 Slog.v(TAG, " + " + info.activityInfo); 6423 } 6424 } 6425 return result; 6426 } 6427 6428 // Returns a packed value as a long: 6429 // 6430 // high 'int'-sized word: link status: undefined/ask/never/always. 6431 // low 'int'-sized word: relative priority among 'always' results. 6432 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 6433 long result = ps.getDomainVerificationStatusForUser(userId); 6434 // if none available, get the master status 6435 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 6436 if (ps.getIntentFilterVerificationInfo() != null) { 6437 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 6438 } 6439 } 6440 return result; 6441 } 6442 6443 private ResolveInfo querySkipCurrentProfileIntents( 6444 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6445 int flags, int sourceUserId) { 6446 if (matchingFilters != null) { 6447 int size = matchingFilters.size(); 6448 for (int i = 0; i < size; i ++) { 6449 CrossProfileIntentFilter filter = matchingFilters.get(i); 6450 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 6451 // Checking if there are activities in the target user that can handle the 6452 // intent. 6453 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6454 resolvedType, flags, sourceUserId); 6455 if (resolveInfo != null) { 6456 return resolveInfo; 6457 } 6458 } 6459 } 6460 } 6461 return null; 6462 } 6463 6464 // Return matching ResolveInfo in target user if any. 6465 private ResolveInfo queryCrossProfileIntents( 6466 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6467 int flags, int sourceUserId, boolean matchInCurrentProfile) { 6468 if (matchingFilters != null) { 6469 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 6470 // match the same intent. For performance reasons, it is better not to 6471 // run queryIntent twice for the same userId 6472 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 6473 int size = matchingFilters.size(); 6474 for (int i = 0; i < size; i++) { 6475 CrossProfileIntentFilter filter = matchingFilters.get(i); 6476 int targetUserId = filter.getTargetUserId(); 6477 boolean skipCurrentProfile = 6478 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 6479 boolean skipCurrentProfileIfNoMatchFound = 6480 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 6481 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 6482 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 6483 // Checking if there are activities in the target user that can handle the 6484 // intent. 6485 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6486 resolvedType, flags, sourceUserId); 6487 if (resolveInfo != null) return resolveInfo; 6488 alreadyTriedUserIds.put(targetUserId, true); 6489 } 6490 } 6491 } 6492 return null; 6493 } 6494 6495 /** 6496 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 6497 * will forward the intent to the filter's target user. 6498 * Otherwise, returns null. 6499 */ 6500 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 6501 String resolvedType, int flags, int sourceUserId) { 6502 int targetUserId = filter.getTargetUserId(); 6503 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 6504 resolvedType, flags, targetUserId); 6505 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 6506 // If all the matches in the target profile are suspended, return null. 6507 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 6508 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 6509 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 6510 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 6511 targetUserId); 6512 } 6513 } 6514 } 6515 return null; 6516 } 6517 6518 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 6519 int sourceUserId, int targetUserId) { 6520 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 6521 long ident = Binder.clearCallingIdentity(); 6522 boolean targetIsProfile; 6523 try { 6524 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 6525 } finally { 6526 Binder.restoreCallingIdentity(ident); 6527 } 6528 String className; 6529 if (targetIsProfile) { 6530 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 6531 } else { 6532 className = FORWARD_INTENT_TO_PARENT; 6533 } 6534 ComponentName forwardingActivityComponentName = new ComponentName( 6535 mAndroidApplication.packageName, className); 6536 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 6537 sourceUserId); 6538 if (!targetIsProfile) { 6539 forwardingActivityInfo.showUserIcon = targetUserId; 6540 forwardingResolveInfo.noResourceId = true; 6541 } 6542 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 6543 forwardingResolveInfo.priority = 0; 6544 forwardingResolveInfo.preferredOrder = 0; 6545 forwardingResolveInfo.match = 0; 6546 forwardingResolveInfo.isDefault = true; 6547 forwardingResolveInfo.filter = filter; 6548 forwardingResolveInfo.targetUserId = targetUserId; 6549 return forwardingResolveInfo; 6550 } 6551 6552 @Override 6553 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 6554 Intent[] specifics, String[] specificTypes, Intent intent, 6555 String resolvedType, int flags, int userId) { 6556 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 6557 specificTypes, intent, resolvedType, flags, userId)); 6558 } 6559 6560 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 6561 Intent[] specifics, String[] specificTypes, Intent intent, 6562 String resolvedType, int flags, int userId) { 6563 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6564 flags = updateFlagsForResolve(flags, userId, intent); 6565 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6566 false /* requireFullPermission */, false /* checkShell */, 6567 "query intent activity options"); 6568 final String resultsAction = intent.getAction(); 6569 6570 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 6571 | PackageManager.GET_RESOLVED_FILTER, userId); 6572 6573 if (DEBUG_INTENT_MATCHING) { 6574 Log.v(TAG, "Query " + intent + ": " + results); 6575 } 6576 6577 int specificsPos = 0; 6578 int N; 6579 6580 // todo: note that the algorithm used here is O(N^2). This 6581 // isn't a problem in our current environment, but if we start running 6582 // into situations where we have more than 5 or 10 matches then this 6583 // should probably be changed to something smarter... 6584 6585 // First we go through and resolve each of the specific items 6586 // that were supplied, taking care of removing any corresponding 6587 // duplicate items in the generic resolve list. 6588 if (specifics != null) { 6589 for (int i=0; i<specifics.length; i++) { 6590 final Intent sintent = specifics[i]; 6591 if (sintent == null) { 6592 continue; 6593 } 6594 6595 if (DEBUG_INTENT_MATCHING) { 6596 Log.v(TAG, "Specific #" + i + ": " + sintent); 6597 } 6598 6599 String action = sintent.getAction(); 6600 if (resultsAction != null && resultsAction.equals(action)) { 6601 // If this action was explicitly requested, then don't 6602 // remove things that have it. 6603 action = null; 6604 } 6605 6606 ResolveInfo ri = null; 6607 ActivityInfo ai = null; 6608 6609 ComponentName comp = sintent.getComponent(); 6610 if (comp == null) { 6611 ri = resolveIntent( 6612 sintent, 6613 specificTypes != null ? specificTypes[i] : null, 6614 flags, userId); 6615 if (ri == null) { 6616 continue; 6617 } 6618 if (ri == mResolveInfo) { 6619 // ACK! Must do something better with this. 6620 } 6621 ai = ri.activityInfo; 6622 comp = new ComponentName(ai.applicationInfo.packageName, 6623 ai.name); 6624 } else { 6625 ai = getActivityInfo(comp, flags, userId); 6626 if (ai == null) { 6627 continue; 6628 } 6629 } 6630 6631 // Look for any generic query activities that are duplicates 6632 // of this specific one, and remove them from the results. 6633 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 6634 N = results.size(); 6635 int j; 6636 for (j=specificsPos; j<N; j++) { 6637 ResolveInfo sri = results.get(j); 6638 if ((sri.activityInfo.name.equals(comp.getClassName()) 6639 && sri.activityInfo.applicationInfo.packageName.equals( 6640 comp.getPackageName())) 6641 || (action != null && sri.filter.matchAction(action))) { 6642 results.remove(j); 6643 if (DEBUG_INTENT_MATCHING) Log.v( 6644 TAG, "Removing duplicate item from " + j 6645 + " due to specific " + specificsPos); 6646 if (ri == null) { 6647 ri = sri; 6648 } 6649 j--; 6650 N--; 6651 } 6652 } 6653 6654 // Add this specific item to its proper place. 6655 if (ri == null) { 6656 ri = new ResolveInfo(); 6657 ri.activityInfo = ai; 6658 } 6659 results.add(specificsPos, ri); 6660 ri.specificIndex = i; 6661 specificsPos++; 6662 } 6663 } 6664 6665 // Now we go through the remaining generic results and remove any 6666 // duplicate actions that are found here. 6667 N = results.size(); 6668 for (int i=specificsPos; i<N-1; i++) { 6669 final ResolveInfo rii = results.get(i); 6670 if (rii.filter == null) { 6671 continue; 6672 } 6673 6674 // Iterate over all of the actions of this result's intent 6675 // filter... typically this should be just one. 6676 final Iterator<String> it = rii.filter.actionsIterator(); 6677 if (it == null) { 6678 continue; 6679 } 6680 while (it.hasNext()) { 6681 final String action = it.next(); 6682 if (resultsAction != null && resultsAction.equals(action)) { 6683 // If this action was explicitly requested, then don't 6684 // remove things that have it. 6685 continue; 6686 } 6687 for (int j=i+1; j<N; j++) { 6688 final ResolveInfo rij = results.get(j); 6689 if (rij.filter != null && rij.filter.hasAction(action)) { 6690 results.remove(j); 6691 if (DEBUG_INTENT_MATCHING) Log.v( 6692 TAG, "Removing duplicate item from " + j 6693 + " due to action " + action + " at " + i); 6694 j--; 6695 N--; 6696 } 6697 } 6698 } 6699 6700 // If the caller didn't request filter information, drop it now 6701 // so we don't have to marshall/unmarshall it. 6702 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6703 rii.filter = null; 6704 } 6705 } 6706 6707 // Filter out the caller activity if so requested. 6708 if (caller != null) { 6709 N = results.size(); 6710 for (int i=0; i<N; i++) { 6711 ActivityInfo ainfo = results.get(i).activityInfo; 6712 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 6713 && caller.getClassName().equals(ainfo.name)) { 6714 results.remove(i); 6715 break; 6716 } 6717 } 6718 } 6719 6720 // If the caller didn't request filter information, 6721 // drop them now so we don't have to 6722 // marshall/unmarshall it. 6723 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6724 N = results.size(); 6725 for (int i=0; i<N; i++) { 6726 results.get(i).filter = null; 6727 } 6728 } 6729 6730 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 6731 return results; 6732 } 6733 6734 @Override 6735 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 6736 String resolvedType, int flags, int userId) { 6737 return new ParceledListSlice<>( 6738 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 6739 } 6740 6741 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 6742 String resolvedType, int flags, int userId) { 6743 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6744 flags = updateFlagsForResolve(flags, userId, intent); 6745 ComponentName comp = intent.getComponent(); 6746 if (comp == null) { 6747 if (intent.getSelector() != null) { 6748 intent = intent.getSelector(); 6749 comp = intent.getComponent(); 6750 } 6751 } 6752 if (comp != null) { 6753 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6754 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 6755 if (ai != null) { 6756 ResolveInfo ri = new ResolveInfo(); 6757 ri.activityInfo = ai; 6758 list.add(ri); 6759 } 6760 return list; 6761 } 6762 6763 // reader 6764 synchronized (mPackages) { 6765 String pkgName = intent.getPackage(); 6766 if (pkgName == null) { 6767 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 6768 } 6769 final PackageParser.Package pkg = mPackages.get(pkgName); 6770 if (pkg != null) { 6771 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 6772 userId); 6773 } 6774 return Collections.emptyList(); 6775 } 6776 } 6777 6778 @Override 6779 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 6780 if (!sUserManager.exists(userId)) return null; 6781 flags = updateFlagsForResolve(flags, userId, intent); 6782 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 6783 if (query != null) { 6784 if (query.size() >= 1) { 6785 // If there is more than one service with the same priority, 6786 // just arbitrarily pick the first one. 6787 return query.get(0); 6788 } 6789 } 6790 return null; 6791 } 6792 6793 @Override 6794 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 6795 String resolvedType, int flags, int userId) { 6796 return new ParceledListSlice<>( 6797 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 6798 } 6799 6800 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 6801 String resolvedType, int flags, int userId) { 6802 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6803 flags = updateFlagsForResolve(flags, userId, intent); 6804 ComponentName comp = intent.getComponent(); 6805 if (comp == null) { 6806 if (intent.getSelector() != null) { 6807 intent = intent.getSelector(); 6808 comp = intent.getComponent(); 6809 } 6810 } 6811 if (comp != null) { 6812 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6813 final ServiceInfo si = getServiceInfo(comp, flags, userId); 6814 if (si != null) { 6815 final ResolveInfo ri = new ResolveInfo(); 6816 ri.serviceInfo = si; 6817 list.add(ri); 6818 } 6819 return list; 6820 } 6821 6822 // reader 6823 synchronized (mPackages) { 6824 String pkgName = intent.getPackage(); 6825 if (pkgName == null) { 6826 return mServices.queryIntent(intent, resolvedType, flags, userId); 6827 } 6828 final PackageParser.Package pkg = mPackages.get(pkgName); 6829 if (pkg != null) { 6830 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 6831 userId); 6832 } 6833 return Collections.emptyList(); 6834 } 6835 } 6836 6837 @Override 6838 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 6839 String resolvedType, int flags, int userId) { 6840 return new ParceledListSlice<>( 6841 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 6842 } 6843 6844 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 6845 Intent intent, String resolvedType, int flags, int userId) { 6846 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6847 flags = updateFlagsForResolve(flags, userId, intent); 6848 ComponentName comp = intent.getComponent(); 6849 if (comp == null) { 6850 if (intent.getSelector() != null) { 6851 intent = intent.getSelector(); 6852 comp = intent.getComponent(); 6853 } 6854 } 6855 if (comp != null) { 6856 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6857 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 6858 if (pi != null) { 6859 final ResolveInfo ri = new ResolveInfo(); 6860 ri.providerInfo = pi; 6861 list.add(ri); 6862 } 6863 return list; 6864 } 6865 6866 // reader 6867 synchronized (mPackages) { 6868 String pkgName = intent.getPackage(); 6869 if (pkgName == null) { 6870 return mProviders.queryIntent(intent, resolvedType, flags, userId); 6871 } 6872 final PackageParser.Package pkg = mPackages.get(pkgName); 6873 if (pkg != null) { 6874 return mProviders.queryIntentForPackage( 6875 intent, resolvedType, flags, pkg.providers, userId); 6876 } 6877 return Collections.emptyList(); 6878 } 6879 } 6880 6881 @Override 6882 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 6883 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6884 flags = updateFlagsForPackage(flags, userId, null); 6885 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 6886 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6887 true /* requireFullPermission */, false /* checkShell */, 6888 "get installed packages"); 6889 6890 // writer 6891 synchronized (mPackages) { 6892 ArrayList<PackageInfo> list; 6893 if (listUninstalled) { 6894 list = new ArrayList<>(mSettings.mPackages.size()); 6895 for (PackageSetting ps : mSettings.mPackages.values()) { 6896 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 6897 continue; 6898 } 6899 final PackageInfo pi = generatePackageInfo(ps, flags, userId); 6900 if (pi != null) { 6901 list.add(pi); 6902 } 6903 } 6904 } else { 6905 list = new ArrayList<>(mPackages.size()); 6906 for (PackageParser.Package p : mPackages.values()) { 6907 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras, 6908 Binder.getCallingUid(), userId)) { 6909 continue; 6910 } 6911 final PackageInfo pi = generatePackageInfo((PackageSetting) 6912 p.mExtras, flags, userId); 6913 if (pi != null) { 6914 list.add(pi); 6915 } 6916 } 6917 } 6918 6919 return new ParceledListSlice<>(list); 6920 } 6921 } 6922 6923 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 6924 String[] permissions, boolean[] tmp, int flags, int userId) { 6925 int numMatch = 0; 6926 final PermissionsState permissionsState = ps.getPermissionsState(); 6927 for (int i=0; i<permissions.length; i++) { 6928 final String permission = permissions[i]; 6929 if (permissionsState.hasPermission(permission, userId)) { 6930 tmp[i] = true; 6931 numMatch++; 6932 } else { 6933 tmp[i] = false; 6934 } 6935 } 6936 if (numMatch == 0) { 6937 return; 6938 } 6939 final PackageInfo pi = generatePackageInfo(ps, flags, userId); 6940 6941 // The above might return null in cases of uninstalled apps or install-state 6942 // skew across users/profiles. 6943 if (pi != null) { 6944 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 6945 if (numMatch == permissions.length) { 6946 pi.requestedPermissions = permissions; 6947 } else { 6948 pi.requestedPermissions = new String[numMatch]; 6949 numMatch = 0; 6950 for (int i=0; i<permissions.length; i++) { 6951 if (tmp[i]) { 6952 pi.requestedPermissions[numMatch] = permissions[i]; 6953 numMatch++; 6954 } 6955 } 6956 } 6957 } 6958 list.add(pi); 6959 } 6960 } 6961 6962 @Override 6963 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 6964 String[] permissions, int flags, int userId) { 6965 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6966 flags = updateFlagsForPackage(flags, userId, permissions); 6967 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6968 true /* requireFullPermission */, false /* checkShell */, 6969 "get packages holding permissions"); 6970 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 6971 6972 // writer 6973 synchronized (mPackages) { 6974 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 6975 boolean[] tmpBools = new boolean[permissions.length]; 6976 if (listUninstalled) { 6977 for (PackageSetting ps : mSettings.mPackages.values()) { 6978 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6979 userId); 6980 } 6981 } else { 6982 for (PackageParser.Package pkg : mPackages.values()) { 6983 PackageSetting ps = (PackageSetting)pkg.mExtras; 6984 if (ps != null) { 6985 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6986 userId); 6987 } 6988 } 6989 } 6990 6991 return new ParceledListSlice<PackageInfo>(list); 6992 } 6993 } 6994 6995 @Override 6996 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6997 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6998 flags = updateFlagsForApplication(flags, userId, null); 6999 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 7000 7001 // writer 7002 synchronized (mPackages) { 7003 ArrayList<ApplicationInfo> list; 7004 if (listUninstalled) { 7005 list = new ArrayList<>(mSettings.mPackages.size()); 7006 for (PackageSetting ps : mSettings.mPackages.values()) { 7007 ApplicationInfo ai; 7008 int effectiveFlags = flags; 7009 if (ps.isSystem()) { 7010 effectiveFlags |= PackageManager.MATCH_ANY_USER; 7011 } 7012 if (ps.pkg != null) { 7013 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7014 continue; 7015 } 7016 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags, 7017 ps.readUserState(userId), userId); 7018 if (ai != null) { 7019 ai.packageName = resolveExternalPackageNameLPr(ps.pkg); 7020 } 7021 } else { 7022 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw 7023 // and already converts to externally visible package name 7024 ai = generateApplicationInfoFromSettingsLPw(ps.name, 7025 Binder.getCallingUid(), effectiveFlags, userId); 7026 } 7027 if (ai != null) { 7028 list.add(ai); 7029 } 7030 } 7031 } else { 7032 list = new ArrayList<>(mPackages.size()); 7033 for (PackageParser.Package p : mPackages.values()) { 7034 if (p.mExtras != null) { 7035 PackageSetting ps = (PackageSetting) p.mExtras; 7036 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7037 continue; 7038 } 7039 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 7040 ps.readUserState(userId), userId); 7041 if (ai != null) { 7042 ai.packageName = resolveExternalPackageNameLPr(p); 7043 list.add(ai); 7044 } 7045 } 7046 } 7047 } 7048 7049 return new ParceledListSlice<>(list); 7050 } 7051 } 7052 7053 @Override 7054 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) { 7055 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7056 return null; 7057 } 7058 7059 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, 7060 "getEphemeralApplications"); 7061 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7062 true /* requireFullPermission */, false /* checkShell */, 7063 "getEphemeralApplications"); 7064 synchronized (mPackages) { 7065 List<InstantAppInfo> instantApps = mInstantAppRegistry 7066 .getInstantAppsLPr(userId); 7067 if (instantApps != null) { 7068 return new ParceledListSlice<>(instantApps); 7069 } 7070 } 7071 return null; 7072 } 7073 7074 @Override 7075 public boolean isInstantApp(String packageName, int userId) { 7076 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7077 true /* requireFullPermission */, false /* checkShell */, 7078 "isInstantApp"); 7079 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7080 return false; 7081 } 7082 7083 if (!isCallerSameApp(packageName)) { 7084 return false; 7085 } 7086 synchronized (mPackages) { 7087 final PackageSetting ps = mSettings.mPackages.get(packageName); 7088 if (ps != null) { 7089 return ps.getInstantApp(userId); 7090 } 7091 } 7092 return false; 7093 } 7094 7095 @Override 7096 public byte[] getInstantAppCookie(String packageName, int userId) { 7097 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7098 return null; 7099 } 7100 7101 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7102 true /* requireFullPermission */, false /* checkShell */, 7103 "getInstantAppCookie"); 7104 if (!isCallerSameApp(packageName)) { 7105 return null; 7106 } 7107 synchronized (mPackages) { 7108 return mInstantAppRegistry.getInstantAppCookieLPw( 7109 packageName, userId); 7110 } 7111 } 7112 7113 @Override 7114 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) { 7115 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7116 return true; 7117 } 7118 7119 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7120 true /* requireFullPermission */, true /* checkShell */, 7121 "setInstantAppCookie"); 7122 if (!isCallerSameApp(packageName)) { 7123 return false; 7124 } 7125 synchronized (mPackages) { 7126 return mInstantAppRegistry.setInstantAppCookieLPw( 7127 packageName, cookie, userId); 7128 } 7129 } 7130 7131 @Override 7132 public Bitmap getInstantAppIcon(String packageName, int userId) { 7133 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7134 return null; 7135 } 7136 7137 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, 7138 "getInstantAppIcon"); 7139 7140 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7141 true /* requireFullPermission */, false /* checkShell */, 7142 "getInstantAppIcon"); 7143 7144 synchronized (mPackages) { 7145 return mInstantAppRegistry.getInstantAppIconLPw( 7146 packageName, userId); 7147 } 7148 } 7149 7150 private boolean isCallerSameApp(String packageName) { 7151 PackageParser.Package pkg = mPackages.get(packageName); 7152 return pkg != null 7153 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 7154 } 7155 7156 @Override 7157 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 7158 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 7159 } 7160 7161 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 7162 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 7163 7164 // reader 7165 synchronized (mPackages) { 7166 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 7167 final int userId = UserHandle.getCallingUserId(); 7168 while (i.hasNext()) { 7169 final PackageParser.Package p = i.next(); 7170 if (p.applicationInfo == null) continue; 7171 7172 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 7173 && !p.applicationInfo.isDirectBootAware(); 7174 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 7175 && p.applicationInfo.isDirectBootAware(); 7176 7177 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 7178 && (!mSafeMode || isSystemApp(p)) 7179 && (matchesUnaware || matchesAware)) { 7180 PackageSetting ps = mSettings.mPackages.get(p.packageName); 7181 if (ps != null) { 7182 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 7183 ps.readUserState(userId), userId); 7184 if (ai != null) { 7185 finalList.add(ai); 7186 } 7187 } 7188 } 7189 } 7190 } 7191 7192 return finalList; 7193 } 7194 7195 @Override 7196 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 7197 if (!sUserManager.exists(userId)) return null; 7198 flags = updateFlagsForComponent(flags, userId, name); 7199 // reader 7200 synchronized (mPackages) { 7201 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 7202 PackageSetting ps = provider != null 7203 ? mSettings.mPackages.get(provider.owner.packageName) 7204 : null; 7205 return ps != null 7206 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 7207 ? PackageParser.generateProviderInfo(provider, flags, 7208 ps.readUserState(userId), userId) 7209 : null; 7210 } 7211 } 7212 7213 /** 7214 * @deprecated 7215 */ 7216 @Deprecated 7217 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 7218 // reader 7219 synchronized (mPackages) { 7220 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 7221 .entrySet().iterator(); 7222 final int userId = UserHandle.getCallingUserId(); 7223 while (i.hasNext()) { 7224 Map.Entry<String, PackageParser.Provider> entry = i.next(); 7225 PackageParser.Provider p = entry.getValue(); 7226 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 7227 7228 if (ps != null && p.syncable 7229 && (!mSafeMode || (p.info.applicationInfo.flags 7230 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 7231 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 7232 ps.readUserState(userId), userId); 7233 if (info != null) { 7234 outNames.add(entry.getKey()); 7235 outInfo.add(info); 7236 } 7237 } 7238 } 7239 } 7240 } 7241 7242 @Override 7243 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 7244 int uid, int flags) { 7245 final int userId = processName != null ? UserHandle.getUserId(uid) 7246 : UserHandle.getCallingUserId(); 7247 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7248 flags = updateFlagsForComponent(flags, userId, processName); 7249 7250 ArrayList<ProviderInfo> finalList = null; 7251 // reader 7252 synchronized (mPackages) { 7253 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 7254 while (i.hasNext()) { 7255 final PackageParser.Provider p = i.next(); 7256 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 7257 if (ps != null && p.info.authority != null 7258 && (processName == null 7259 || (p.info.processName.equals(processName) 7260 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 7261 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 7262 if (finalList == null) { 7263 finalList = new ArrayList<ProviderInfo>(3); 7264 } 7265 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 7266 ps.readUserState(userId), userId); 7267 if (info != null) { 7268 finalList.add(info); 7269 } 7270 } 7271 } 7272 } 7273 7274 if (finalList != null) { 7275 Collections.sort(finalList, mProviderInitOrderSorter); 7276 return new ParceledListSlice<ProviderInfo>(finalList); 7277 } 7278 7279 return ParceledListSlice.emptyList(); 7280 } 7281 7282 @Override 7283 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 7284 // reader 7285 synchronized (mPackages) { 7286 final PackageParser.Instrumentation i = mInstrumentation.get(name); 7287 return PackageParser.generateInstrumentationInfo(i, flags); 7288 } 7289 } 7290 7291 @Override 7292 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 7293 String targetPackage, int flags) { 7294 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 7295 } 7296 7297 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 7298 int flags) { 7299 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 7300 7301 // reader 7302 synchronized (mPackages) { 7303 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 7304 while (i.hasNext()) { 7305 final PackageParser.Instrumentation p = i.next(); 7306 if (targetPackage == null 7307 || targetPackage.equals(p.info.targetPackage)) { 7308 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 7309 flags); 7310 if (ii != null) { 7311 finalList.add(ii); 7312 } 7313 } 7314 } 7315 } 7316 7317 return finalList; 7318 } 7319 7320 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 7321 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 7322 if (overlays == null) { 7323 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 7324 return; 7325 } 7326 for (PackageParser.Package opkg : overlays.values()) { 7327 // Not much to do if idmap fails: we already logged the error 7328 // and we certainly don't want to abort installation of pkg simply 7329 // because an overlay didn't fit properly. For these reasons, 7330 // ignore the return value of createIdmapForPackagePairLI. 7331 createIdmapForPackagePairLI(pkg, opkg); 7332 } 7333 } 7334 7335 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 7336 PackageParser.Package opkg) { 7337 if (!opkg.mTrustedOverlay) { 7338 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 7339 opkg.baseCodePath + ": overlay not trusted"); 7340 return false; 7341 } 7342 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 7343 if (overlaySet == null) { 7344 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 7345 opkg.baseCodePath + " but target package has no known overlays"); 7346 return false; 7347 } 7348 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 7349 // TODO: generate idmap for split APKs 7350 try { 7351 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 7352 } catch (InstallerException e) { 7353 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 7354 + opkg.baseCodePath); 7355 return false; 7356 } 7357 PackageParser.Package[] overlayArray = 7358 overlaySet.values().toArray(new PackageParser.Package[0]); 7359 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 7360 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 7361 return p1.mOverlayPriority - p2.mOverlayPriority; 7362 } 7363 }; 7364 Arrays.sort(overlayArray, cmp); 7365 7366 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 7367 int i = 0; 7368 for (PackageParser.Package p : overlayArray) { 7369 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 7370 } 7371 return true; 7372 } 7373 7374 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 7375 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]"); 7376 try { 7377 scanDirLI(dir, parseFlags, scanFlags, currentTime); 7378 } finally { 7379 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7380 } 7381 } 7382 7383 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 7384 final File[] files = dir.listFiles(); 7385 if (ArrayUtils.isEmpty(files)) { 7386 Log.d(TAG, "No files in app dir " + dir); 7387 return; 7388 } 7389 7390 if (DEBUG_PACKAGE_SCANNING) { 7391 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 7392 + " flags=0x" + Integer.toHexString(parseFlags)); 7393 } 7394 ParallelPackageParser parallelPackageParser = new ParallelPackageParser( 7395 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir); 7396 7397 // Submit files for parsing in parallel 7398 int fileCount = 0; 7399 for (File file : files) { 7400 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 7401 && !PackageInstallerService.isStageName(file.getName()); 7402 if (!isPackage) { 7403 // Ignore entries which are not packages 7404 continue; 7405 } 7406 parallelPackageParser.submit(file, parseFlags); 7407 fileCount++; 7408 } 7409 7410 // Process results one by one 7411 for (; fileCount > 0; fileCount--) { 7412 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); 7413 Throwable throwable = parseResult.throwable; 7414 int errorCode = PackageManager.INSTALL_SUCCEEDED; 7415 7416 if (throwable == null) { 7417 // Static shared libraries have synthetic package names 7418 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) { 7419 renameStaticSharedLibraryPackage(parseResult.pkg); 7420 } 7421 try { 7422 if (errorCode == PackageManager.INSTALL_SUCCEEDED) { 7423 scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags, 7424 currentTime, null); 7425 } 7426 } catch (PackageManagerException e) { 7427 errorCode = e.error; 7428 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage()); 7429 } 7430 } else if (throwable instanceof PackageParser.PackageParserException) { 7431 PackageParser.PackageParserException e = (PackageParser.PackageParserException) 7432 throwable; 7433 errorCode = e.error; 7434 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage()); 7435 } else { 7436 throw new IllegalStateException("Unexpected exception occurred while parsing " 7437 + parseResult.scanFile, throwable); 7438 } 7439 7440 // Delete invalid userdata apps 7441 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 7442 errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) { 7443 logCriticalInfo(Log.WARN, 7444 "Deleting invalid package at " + parseResult.scanFile); 7445 removeCodePathLI(parseResult.scanFile); 7446 } 7447 } 7448 parallelPackageParser.close(); 7449 } 7450 7451 private static File getSettingsProblemFile() { 7452 File dataDir = Environment.getDataDirectory(); 7453 File systemDir = new File(dataDir, "system"); 7454 File fname = new File(systemDir, "uiderrors.txt"); 7455 return fname; 7456 } 7457 7458 static void reportSettingsProblem(int priority, String msg) { 7459 logCriticalInfo(priority, msg); 7460 } 7461 7462 static void logCriticalInfo(int priority, String msg) { 7463 Slog.println(priority, TAG, msg); 7464 EventLogTags.writePmCriticalInfo(msg); 7465 try { 7466 File fname = getSettingsProblemFile(); 7467 FileOutputStream out = new FileOutputStream(fname, true); 7468 PrintWriter pw = new FastPrintWriter(out); 7469 SimpleDateFormat formatter = new SimpleDateFormat(); 7470 String dateString = formatter.format(new Date(System.currentTimeMillis())); 7471 pw.println(dateString + ": " + msg); 7472 pw.close(); 7473 FileUtils.setPermissions( 7474 fname.toString(), 7475 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 7476 -1, -1); 7477 } catch (java.io.IOException e) { 7478 } 7479 } 7480 7481 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 7482 if (srcFile.isDirectory()) { 7483 final File baseFile = new File(pkg.baseCodePath); 7484 long maxModifiedTime = baseFile.lastModified(); 7485 if (pkg.splitCodePaths != null) { 7486 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 7487 final File splitFile = new File(pkg.splitCodePaths[i]); 7488 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 7489 } 7490 } 7491 return maxModifiedTime; 7492 } 7493 return srcFile.lastModified(); 7494 } 7495 7496 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 7497 final int policyFlags) throws PackageManagerException { 7498 // When upgrading from pre-N MR1, verify the package time stamp using the package 7499 // directory and not the APK file. 7500 final long lastModifiedTime = mIsPreNMR1Upgrade 7501 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile); 7502 if (ps != null 7503 && ps.codePath.equals(srcFile) 7504 && ps.timeStamp == lastModifiedTime 7505 && !isCompatSignatureUpdateNeeded(pkg) 7506 && !isRecoverSignatureUpdateNeeded(pkg)) { 7507 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 7508 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7509 ArraySet<PublicKey> signingKs; 7510 synchronized (mPackages) { 7511 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 7512 } 7513 if (ps.signatures.mSignatures != null 7514 && ps.signatures.mSignatures.length != 0 7515 && signingKs != null) { 7516 // Optimization: reuse the existing cached certificates 7517 // if the package appears to be unchanged. 7518 pkg.mSignatures = ps.signatures.mSignatures; 7519 pkg.mSigningKeys = signingKs; 7520 return; 7521 } 7522 7523 Slog.w(TAG, "PackageSetting for " + ps.name 7524 + " is missing signatures. Collecting certs again to recover them."); 7525 } else { 7526 Slog.i(TAG, srcFile.toString() + " changed; collecting certs"); 7527 } 7528 7529 try { 7530 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 7531 PackageParser.collectCertificates(pkg, policyFlags); 7532 } catch (PackageParserException e) { 7533 throw PackageManagerException.from(e); 7534 } finally { 7535 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7536 } 7537 } 7538 7539 /** 7540 * Traces a package scan. 7541 * @see #scanPackageLI(File, int, int, long, UserHandle) 7542 */ 7543 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 7544 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7545 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 7546 try { 7547 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 7548 } finally { 7549 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7550 } 7551 } 7552 7553 /** 7554 * Scans a package and returns the newly parsed package. 7555 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 7556 */ 7557 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 7558 long currentTime, UserHandle user) throws PackageManagerException { 7559 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 7560 PackageParser pp = new PackageParser(); 7561 pp.setSeparateProcesses(mSeparateProcesses); 7562 pp.setOnlyCoreApps(mOnlyCore); 7563 pp.setDisplayMetrics(mMetrics); 7564 7565 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 7566 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 7567 } 7568 7569 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 7570 final PackageParser.Package pkg; 7571 try { 7572 pkg = pp.parsePackage(scanFile, parseFlags); 7573 } catch (PackageParserException e) { 7574 throw PackageManagerException.from(e); 7575 } finally { 7576 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7577 } 7578 7579 // Static shared libraries have synthetic package names 7580 if (pkg.applicationInfo.isStaticSharedLibrary()) { 7581 renameStaticSharedLibraryPackage(pkg); 7582 } 7583 7584 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 7585 } 7586 7587 /** 7588 * Scans a package and returns the newly parsed package. 7589 * @throws PackageManagerException on a parse error. 7590 */ 7591 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 7592 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 7593 throws PackageManagerException { 7594 // If the package has children and this is the first dive in the function 7595 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 7596 // packages (parent and children) would be successfully scanned before the 7597 // actual scan since scanning mutates internal state and we want to atomically 7598 // install the package and its children. 7599 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7600 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7601 scanFlags |= SCAN_CHECK_ONLY; 7602 } 7603 } else { 7604 scanFlags &= ~SCAN_CHECK_ONLY; 7605 } 7606 7607 // Scan the parent 7608 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 7609 scanFlags, currentTime, user); 7610 7611 // Scan the children 7612 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7613 for (int i = 0; i < childCount; i++) { 7614 PackageParser.Package childPackage = pkg.childPackages.get(i); 7615 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 7616 currentTime, user); 7617 } 7618 7619 7620 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7621 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 7622 } 7623 7624 return scannedPkg; 7625 } 7626 7627 /** 7628 * Scans a package and returns the newly parsed package. 7629 * @throws PackageManagerException on a parse error. 7630 */ 7631 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 7632 int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 7633 throws PackageManagerException { 7634 PackageSetting ps = null; 7635 PackageSetting updatedPkg; 7636 // reader 7637 synchronized (mPackages) { 7638 // Look to see if we already know about this package. 7639 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName); 7640 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 7641 // This package has been renamed to its original name. Let's 7642 // use that. 7643 ps = mSettings.getPackageLPr(oldName); 7644 } 7645 // If there was no original package, see one for the real package name. 7646 if (ps == null) { 7647 ps = mSettings.getPackageLPr(pkg.packageName); 7648 } 7649 // Check to see if this package could be hiding/updating a system 7650 // package. Must look for it either under the original or real 7651 // package name depending on our state. 7652 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 7653 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 7654 7655 // If this is a package we don't know about on the system partition, we 7656 // may need to remove disabled child packages on the system partition 7657 // or may need to not add child packages if the parent apk is updated 7658 // on the data partition and no longer defines this child package. 7659 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7660 // If this is a parent package for an updated system app and this system 7661 // app got an OTA update which no longer defines some of the child packages 7662 // we have to prune them from the disabled system packages. 7663 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 7664 if (disabledPs != null) { 7665 final int scannedChildCount = (pkg.childPackages != null) 7666 ? pkg.childPackages.size() : 0; 7667 final int disabledChildCount = disabledPs.childPackageNames != null 7668 ? disabledPs.childPackageNames.size() : 0; 7669 for (int i = 0; i < disabledChildCount; i++) { 7670 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 7671 boolean disabledPackageAvailable = false; 7672 for (int j = 0; j < scannedChildCount; j++) { 7673 PackageParser.Package childPkg = pkg.childPackages.get(j); 7674 if (childPkg.packageName.equals(disabledChildPackageName)) { 7675 disabledPackageAvailable = true; 7676 break; 7677 } 7678 } 7679 if (!disabledPackageAvailable) { 7680 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 7681 } 7682 } 7683 } 7684 } 7685 } 7686 7687 boolean updatedPkgBetter = false; 7688 // First check if this is a system package that may involve an update 7689 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7690 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 7691 // it needs to drop FLAG_PRIVILEGED. 7692 if (locationIsPrivileged(scanFile)) { 7693 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7694 } else { 7695 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7696 } 7697 7698 if (ps != null && !ps.codePath.equals(scanFile)) { 7699 // The path has changed from what was last scanned... check the 7700 // version of the new path against what we have stored to determine 7701 // what to do. 7702 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 7703 if (pkg.mVersionCode <= ps.versionCode) { 7704 // The system package has been updated and the code path does not match 7705 // Ignore entry. Skip it. 7706 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 7707 + " ignored: updated version " + ps.versionCode 7708 + " better than this " + pkg.mVersionCode); 7709 if (!updatedPkg.codePath.equals(scanFile)) { 7710 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 7711 + ps.name + " changing from " + updatedPkg.codePathString 7712 + " to " + scanFile); 7713 updatedPkg.codePath = scanFile; 7714 updatedPkg.codePathString = scanFile.toString(); 7715 updatedPkg.resourcePath = scanFile; 7716 updatedPkg.resourcePathString = scanFile.toString(); 7717 } 7718 updatedPkg.pkg = pkg; 7719 updatedPkg.versionCode = pkg.mVersionCode; 7720 7721 // Update the disabled system child packages to point to the package too. 7722 final int childCount = updatedPkg.childPackageNames != null 7723 ? updatedPkg.childPackageNames.size() : 0; 7724 for (int i = 0; i < childCount; i++) { 7725 String childPackageName = updatedPkg.childPackageNames.get(i); 7726 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 7727 childPackageName); 7728 if (updatedChildPkg != null) { 7729 updatedChildPkg.pkg = pkg; 7730 updatedChildPkg.versionCode = pkg.mVersionCode; 7731 } 7732 } 7733 7734 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 7735 + scanFile + " ignored: updated version " + ps.versionCode 7736 + " better than this " + pkg.mVersionCode); 7737 } else { 7738 // The current app on the system partition is better than 7739 // what we have updated to on the data partition; switch 7740 // back to the system partition version. 7741 // At this point, its safely assumed that package installation for 7742 // apps in system partition will go through. If not there won't be a working 7743 // version of the app 7744 // writer 7745 synchronized (mPackages) { 7746 // Just remove the loaded entries from package lists. 7747 mPackages.remove(ps.name); 7748 } 7749 7750 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7751 + " reverting from " + ps.codePathString 7752 + ": new version " + pkg.mVersionCode 7753 + " better than installed " + ps.versionCode); 7754 7755 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7756 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7757 synchronized (mInstallLock) { 7758 args.cleanUpResourcesLI(); 7759 } 7760 synchronized (mPackages) { 7761 mSettings.enableSystemPackageLPw(ps.name); 7762 } 7763 updatedPkgBetter = true; 7764 } 7765 } 7766 } 7767 7768 if (updatedPkg != null) { 7769 // An updated system app will not have the PARSE_IS_SYSTEM flag set 7770 // initially 7771 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 7772 7773 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 7774 // flag set initially 7775 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 7776 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 7777 } 7778 } 7779 7780 // Verify certificates against what was last scanned 7781 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 7782 7783 /* 7784 * A new system app appeared, but we already had a non-system one of the 7785 * same name installed earlier. 7786 */ 7787 boolean shouldHideSystemApp = false; 7788 if (updatedPkg == null && ps != null 7789 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 7790 /* 7791 * Check to make sure the signatures match first. If they don't, 7792 * wipe the installed application and its data. 7793 */ 7794 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 7795 != PackageManager.SIGNATURE_MATCH) { 7796 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 7797 + " signatures don't match existing userdata copy; removing"); 7798 try (PackageFreezer freezer = freezePackage(pkg.packageName, 7799 "scanPackageInternalLI")) { 7800 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 7801 } 7802 ps = null; 7803 } else { 7804 /* 7805 * If the newly-added system app is an older version than the 7806 * already installed version, hide it. It will be scanned later 7807 * and re-added like an update. 7808 */ 7809 if (pkg.mVersionCode <= ps.versionCode) { 7810 shouldHideSystemApp = true; 7811 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 7812 + " but new version " + pkg.mVersionCode + " better than installed " 7813 + ps.versionCode + "; hiding system"); 7814 } else { 7815 /* 7816 * The newly found system app is a newer version that the 7817 * one previously installed. Simply remove the 7818 * already-installed application and replace it with our own 7819 * while keeping the application data. 7820 */ 7821 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7822 + " reverting from " + ps.codePathString + ": new version " 7823 + pkg.mVersionCode + " better than installed " + ps.versionCode); 7824 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7825 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7826 synchronized (mInstallLock) { 7827 args.cleanUpResourcesLI(); 7828 } 7829 } 7830 } 7831 } 7832 7833 // The apk is forward locked (not public) if its code and resources 7834 // are kept in different files. (except for app in either system or 7835 // vendor path). 7836 // TODO grab this value from PackageSettings 7837 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7838 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 7839 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 7840 } 7841 } 7842 7843 // TODO: extend to support forward-locked splits 7844 String resourcePath = null; 7845 String baseResourcePath = null; 7846 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 7847 if (ps != null && ps.resourcePathString != null) { 7848 resourcePath = ps.resourcePathString; 7849 baseResourcePath = ps.resourcePathString; 7850 } else { 7851 // Should not happen at all. Just log an error. 7852 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 7853 } 7854 } else { 7855 resourcePath = pkg.codePath; 7856 baseResourcePath = pkg.baseCodePath; 7857 } 7858 7859 // Set application objects path explicitly. 7860 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 7861 pkg.setApplicationInfoCodePath(pkg.codePath); 7862 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 7863 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 7864 pkg.setApplicationInfoResourcePath(resourcePath); 7865 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 7866 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 7867 7868 final int userId = ((user == null) ? 0 : user.getIdentifier()); 7869 if (ps != null && ps.getInstantApp(userId)) { 7870 scanFlags |= SCAN_AS_INSTANT_APP; 7871 } 7872 7873 // Note that we invoke the following method only if we are about to unpack an application 7874 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 7875 | SCAN_UPDATE_SIGNATURE, currentTime, user); 7876 7877 /* 7878 * If the system app should be overridden by a previously installed 7879 * data, hide the system app now and let the /data/app scan pick it up 7880 * again. 7881 */ 7882 if (shouldHideSystemApp) { 7883 synchronized (mPackages) { 7884 mSettings.disableSystemPackageLPw(pkg.packageName, true); 7885 } 7886 } 7887 7888 return scannedPkg; 7889 } 7890 7891 private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) { 7892 // Derive the new package synthetic package name 7893 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER 7894 + pkg.staticSharedLibVersion); 7895 } 7896 7897 private static String fixProcessName(String defProcessName, 7898 String processName) { 7899 if (processName == null) { 7900 return defProcessName; 7901 } 7902 return processName; 7903 } 7904 7905 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 7906 throws PackageManagerException { 7907 if (pkgSetting.signatures.mSignatures != null) { 7908 // Already existing package. Make sure signatures match 7909 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 7910 == PackageManager.SIGNATURE_MATCH; 7911 if (!match) { 7912 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 7913 == PackageManager.SIGNATURE_MATCH; 7914 } 7915 if (!match) { 7916 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 7917 == PackageManager.SIGNATURE_MATCH; 7918 } 7919 if (!match) { 7920 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 7921 + pkg.packageName + " signatures do not match the " 7922 + "previously installed version; ignoring!"); 7923 } 7924 } 7925 7926 // Check for shared user signatures 7927 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 7928 // Already existing package. Make sure signatures match 7929 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7930 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 7931 if (!match) { 7932 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 7933 == PackageManager.SIGNATURE_MATCH; 7934 } 7935 if (!match) { 7936 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 7937 == PackageManager.SIGNATURE_MATCH; 7938 } 7939 if (!match) { 7940 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 7941 "Package " + pkg.packageName 7942 + " has no signatures that match those in shared user " 7943 + pkgSetting.sharedUser.name + "; ignoring!"); 7944 } 7945 } 7946 } 7947 7948 /** 7949 * Enforces that only the system UID or root's UID can call a method exposed 7950 * via Binder. 7951 * 7952 * @param message used as message if SecurityException is thrown 7953 * @throws SecurityException if the caller is not system or root 7954 */ 7955 private static final void enforceSystemOrRoot(String message) { 7956 final int uid = Binder.getCallingUid(); 7957 if (uid != Process.SYSTEM_UID && uid != 0) { 7958 throw new SecurityException(message); 7959 } 7960 } 7961 7962 @Override 7963 public void performFstrimIfNeeded() { 7964 enforceSystemOrRoot("Only the system can request fstrim"); 7965 7966 // Before everything else, see whether we need to fstrim. 7967 try { 7968 IStorageManager sm = PackageHelper.getStorageManager(); 7969 if (sm != null) { 7970 boolean doTrim = false; 7971 final long interval = android.provider.Settings.Global.getLong( 7972 mContext.getContentResolver(), 7973 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 7974 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 7975 if (interval > 0) { 7976 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance(); 7977 if (timeSinceLast > interval) { 7978 doTrim = true; 7979 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 7980 + "; running immediately"); 7981 } 7982 } 7983 if (doTrim) { 7984 final boolean dexOptDialogShown; 7985 synchronized (mPackages) { 7986 dexOptDialogShown = mDexOptDialogShown; 7987 } 7988 if (!isFirstBoot() && dexOptDialogShown) { 7989 try { 7990 ActivityManager.getService().showBootMessage( 7991 mContext.getResources().getString( 7992 R.string.android_upgrading_fstrim), true); 7993 } catch (RemoteException e) { 7994 } 7995 } 7996 sm.runMaintenance(); 7997 } 7998 } else { 7999 Slog.e(TAG, "storageManager service unavailable!"); 8000 } 8001 } catch (RemoteException e) { 8002 // Can't happen; StorageManagerService is local 8003 } 8004 } 8005 8006 @Override 8007 public void updatePackagesIfNeeded() { 8008 enforceSystemOrRoot("Only the system can request package update"); 8009 8010 // We need to re-extract after an OTA. 8011 boolean causeUpgrade = isUpgrade(); 8012 8013 // First boot or factory reset. 8014 // Note: we also handle devices that are upgrading to N right now as if it is their 8015 // first boot, as they do not have profile data. 8016 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 8017 8018 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 8019 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 8020 8021 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 8022 return; 8023 } 8024 8025 List<PackageParser.Package> pkgs; 8026 synchronized (mPackages) { 8027 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 8028 } 8029 8030 final long startTime = System.nanoTime(); 8031 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 8032 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 8033 8034 final int elapsedTimeSeconds = 8035 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 8036 8037 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 8038 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 8039 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 8040 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 8041 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 8042 } 8043 8044 /** 8045 * Performs dexopt on the set of packages in {@code packages} and returns an int array 8046 * containing statistics about the invocation. The array consists of three elements, 8047 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 8048 * and {@code numberOfPackagesFailed}. 8049 */ 8050 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 8051 String compilerFilter) { 8052 8053 int numberOfPackagesVisited = 0; 8054 int numberOfPackagesOptimized = 0; 8055 int numberOfPackagesSkipped = 0; 8056 int numberOfPackagesFailed = 0; 8057 final int numberOfPackagesToDexopt = pkgs.size(); 8058 8059 for (PackageParser.Package pkg : pkgs) { 8060 numberOfPackagesVisited++; 8061 8062 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 8063 if (DEBUG_DEXOPT) { 8064 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 8065 } 8066 numberOfPackagesSkipped++; 8067 continue; 8068 } 8069 8070 if (DEBUG_DEXOPT) { 8071 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 8072 numberOfPackagesToDexopt + ": " + pkg.packageName); 8073 } 8074 8075 if (showDialog) { 8076 try { 8077 ActivityManager.getService().showBootMessage( 8078 mContext.getResources().getString(R.string.android_upgrading_apk, 8079 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 8080 } catch (RemoteException e) { 8081 } 8082 synchronized (mPackages) { 8083 mDexOptDialogShown = true; 8084 } 8085 } 8086 8087 // If the OTA updates a system app which was previously preopted to a non-preopted state 8088 // the app might end up being verified at runtime. That's because by default the apps 8089 // are verify-profile but for preopted apps there's no profile. 8090 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 8091 // that before the OTA the app was preopted) the app gets compiled with a non-profile 8092 // filter (by default interpret-only). 8093 // Note that at this stage unused apps are already filtered. 8094 if (isSystemApp(pkg) && 8095 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 8096 !Environment.getReferenceProfile(pkg.packageName).exists()) { 8097 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 8098 } 8099 8100 // checkProfiles is false to avoid merging profiles during boot which 8101 // might interfere with background compilation (b/28612421). 8102 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 8103 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 8104 // trade-off worth doing to save boot time work. 8105 int dexOptStatus = performDexOptTraced(pkg.packageName, 8106 false /* checkProfiles */, 8107 compilerFilter, 8108 false /* force */); 8109 switch (dexOptStatus) { 8110 case PackageDexOptimizer.DEX_OPT_PERFORMED: 8111 numberOfPackagesOptimized++; 8112 break; 8113 case PackageDexOptimizer.DEX_OPT_SKIPPED: 8114 numberOfPackagesSkipped++; 8115 break; 8116 case PackageDexOptimizer.DEX_OPT_FAILED: 8117 numberOfPackagesFailed++; 8118 break; 8119 default: 8120 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 8121 break; 8122 } 8123 } 8124 8125 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 8126 numberOfPackagesFailed }; 8127 } 8128 8129 @Override 8130 public void notifyPackageUse(String packageName, int reason) { 8131 synchronized (mPackages) { 8132 PackageParser.Package p = mPackages.get(packageName); 8133 if (p == null) { 8134 return; 8135 } 8136 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 8137 } 8138 } 8139 8140 @Override 8141 public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) { 8142 int userId = UserHandle.getCallingUserId(); 8143 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId); 8144 if (ai == null) { 8145 Slog.w(TAG, "Loading a package that does not exist for the calling user. package=" 8146 + loadingPackageName + ", user=" + userId); 8147 return; 8148 } 8149 mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId); 8150 } 8151 8152 // TODO: this is not used nor needed. Delete it. 8153 @Override 8154 public boolean performDexOptIfNeeded(String packageName) { 8155 int dexOptStatus = performDexOptTraced(packageName, 8156 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 8157 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8158 } 8159 8160 @Override 8161 public boolean performDexOpt(String packageName, 8162 boolean checkProfiles, int compileReason, boolean force) { 8163 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 8164 getCompilerFilterForReason(compileReason), force); 8165 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8166 } 8167 8168 @Override 8169 public boolean performDexOptMode(String packageName, 8170 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8171 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 8172 targetCompilerFilter, force); 8173 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8174 } 8175 8176 private int performDexOptTraced(String packageName, 8177 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8178 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 8179 try { 8180 return performDexOptInternal(packageName, checkProfiles, 8181 targetCompilerFilter, force); 8182 } finally { 8183 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8184 } 8185 } 8186 8187 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 8188 // if the package can now be considered up to date for the given filter. 8189 private int performDexOptInternal(String packageName, 8190 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8191 PackageParser.Package p; 8192 synchronized (mPackages) { 8193 p = mPackages.get(packageName); 8194 if (p == null) { 8195 // Package could not be found. Report failure. 8196 return PackageDexOptimizer.DEX_OPT_FAILED; 8197 } 8198 mPackageUsage.maybeWriteAsync(mPackages); 8199 mCompilerStats.maybeWriteAsync(); 8200 } 8201 long callingId = Binder.clearCallingIdentity(); 8202 try { 8203 synchronized (mInstallLock) { 8204 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 8205 targetCompilerFilter, force); 8206 } 8207 } finally { 8208 Binder.restoreCallingIdentity(callingId); 8209 } 8210 } 8211 8212 public ArraySet<String> getOptimizablePackages() { 8213 ArraySet<String> pkgs = new ArraySet<String>(); 8214 synchronized (mPackages) { 8215 for (PackageParser.Package p : mPackages.values()) { 8216 if (PackageDexOptimizer.canOptimizePackage(p)) { 8217 pkgs.add(p.packageName); 8218 } 8219 } 8220 } 8221 return pkgs; 8222 } 8223 8224 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 8225 boolean checkProfiles, String targetCompilerFilter, 8226 boolean force) { 8227 // Select the dex optimizer based on the force parameter. 8228 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 8229 // allocate an object here. 8230 PackageDexOptimizer pdo = force 8231 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 8232 : mPackageDexOptimizer; 8233 8234 // Optimize all dependencies first. Note: we ignore the return value and march on 8235 // on errors. 8236 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 8237 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 8238 if (!deps.isEmpty()) { 8239 for (PackageParser.Package depPackage : deps) { 8240 // TODO: Analyze and investigate if we (should) profile libraries. 8241 // Currently this will do a full compilation of the library by default. 8242 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 8243 false /* checkProfiles */, 8244 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 8245 getOrCreateCompilerPackageStats(depPackage)); 8246 } 8247 } 8248 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 8249 targetCompilerFilter, getOrCreateCompilerPackageStats(p)); 8250 } 8251 8252 // Performs dexopt on the used secondary dex files belonging to the given package. 8253 // Returns true if all dex files were process successfully (which could mean either dexopt or 8254 // skip). Returns false if any of the files caused errors. 8255 @Override 8256 public boolean performDexOptSecondary(String packageName, String compilerFilter, 8257 boolean force) { 8258 return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); 8259 } 8260 8261 /** 8262 * Reconcile the information we have about the secondary dex files belonging to 8263 * {@code packagName} and the actual dex files. For all dex files that were 8264 * deleted, update the internal records and delete the generated oat files. 8265 */ 8266 @Override 8267 public void reconcileSecondaryDexFiles(String packageName) { 8268 mDexManager.reconcileSecondaryDexFiles(packageName); 8269 } 8270 8271 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject 8272 // a reference there. 8273 /*package*/ DexManager getDexManager() { 8274 return mDexManager; 8275 } 8276 8277 /** 8278 * Execute the background dexopt job immediately. 8279 */ 8280 @Override 8281 public boolean runBackgroundDexoptJob() { 8282 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext); 8283 } 8284 8285 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 8286 if (p.usesLibraries != null || p.usesOptionalLibraries != null 8287 || p.usesStaticLibraries != null) { 8288 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 8289 Set<String> collectedNames = new HashSet<>(); 8290 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 8291 8292 retValue.remove(p); 8293 8294 return retValue; 8295 } else { 8296 return Collections.emptyList(); 8297 } 8298 } 8299 8300 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 8301 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) { 8302 if (!collectedNames.contains(p.packageName)) { 8303 collectedNames.add(p.packageName); 8304 collected.add(p); 8305 8306 if (p.usesLibraries != null) { 8307 findSharedNonSystemLibrariesRecursive(p.usesLibraries, 8308 null, collected, collectedNames); 8309 } 8310 if (p.usesOptionalLibraries != null) { 8311 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, 8312 null, collected, collectedNames); 8313 } 8314 if (p.usesStaticLibraries != null) { 8315 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries, 8316 p.usesStaticLibrariesVersions, collected, collectedNames); 8317 } 8318 } 8319 } 8320 8321 private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions, 8322 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) { 8323 final int libNameCount = libs.size(); 8324 for (int i = 0; i < libNameCount; i++) { 8325 String libName = libs.get(i); 8326 int version = (versions != null && versions.length == libNameCount) 8327 ? versions[i] : PackageManager.VERSION_CODE_HIGHEST; 8328 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version); 8329 if (libPkg != null) { 8330 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 8331 } 8332 } 8333 } 8334 8335 private PackageParser.Package findSharedNonSystemLibrary(String name, int version) { 8336 synchronized (mPackages) { 8337 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version); 8338 if (libEntry != null) { 8339 return mPackages.get(libEntry.apk); 8340 } 8341 return null; 8342 } 8343 } 8344 8345 private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) { 8346 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 8347 if (versionedLib == null) { 8348 return null; 8349 } 8350 return versionedLib.get(version); 8351 } 8352 8353 private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) { 8354 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get( 8355 pkg.staticSharedLibName); 8356 if (versionedLib == null) { 8357 return null; 8358 } 8359 int previousLibVersion = -1; 8360 final int versionCount = versionedLib.size(); 8361 for (int i = 0; i < versionCount; i++) { 8362 final int libVersion = versionedLib.keyAt(i); 8363 if (libVersion < pkg.staticSharedLibVersion) { 8364 previousLibVersion = Math.max(previousLibVersion, libVersion); 8365 } 8366 } 8367 if (previousLibVersion >= 0) { 8368 return versionedLib.get(previousLibVersion); 8369 } 8370 return null; 8371 } 8372 8373 public void shutdown() { 8374 mPackageUsage.writeNow(mPackages); 8375 mCompilerStats.writeNow(); 8376 } 8377 8378 @Override 8379 public void dumpProfiles(String packageName) { 8380 PackageParser.Package pkg; 8381 synchronized (mPackages) { 8382 pkg = mPackages.get(packageName); 8383 if (pkg == null) { 8384 throw new IllegalArgumentException("Unknown package: " + packageName); 8385 } 8386 } 8387 /* Only the shell, root, or the app user should be able to dump profiles. */ 8388 int callingUid = Binder.getCallingUid(); 8389 if (callingUid != Process.SHELL_UID && 8390 callingUid != Process.ROOT_UID && 8391 callingUid != pkg.applicationInfo.uid) { 8392 throw new SecurityException("dumpProfiles"); 8393 } 8394 8395 synchronized (mInstallLock) { 8396 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 8397 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 8398 try { 8399 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 8400 String codePaths = TextUtils.join(";", allCodePaths); 8401 mInstaller.dumpProfiles(sharedGid, packageName, codePaths); 8402 } catch (InstallerException e) { 8403 Slog.w(TAG, "Failed to dump profiles", e); 8404 } 8405 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8406 } 8407 } 8408 8409 @Override 8410 public void forceDexOpt(String packageName) { 8411 enforceSystemOrRoot("forceDexOpt"); 8412 8413 PackageParser.Package pkg; 8414 synchronized (mPackages) { 8415 pkg = mPackages.get(packageName); 8416 if (pkg == null) { 8417 throw new IllegalArgumentException("Unknown package: " + packageName); 8418 } 8419 } 8420 8421 synchronized (mInstallLock) { 8422 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 8423 8424 // Whoever is calling forceDexOpt wants a fully compiled package. 8425 // Don't use profiles since that may cause compilation to be skipped. 8426 final int res = performDexOptInternalWithDependenciesLI(pkg, 8427 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 8428 true /* force */); 8429 8430 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8431 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 8432 throw new IllegalStateException("Failed to dexopt: " + res); 8433 } 8434 } 8435 } 8436 8437 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 8438 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8439 Slog.w(TAG, "Unable to update from " + oldPkg.name 8440 + " to " + newPkg.packageName 8441 + ": old package not in system partition"); 8442 return false; 8443 } else if (mPackages.get(oldPkg.name) != null) { 8444 Slog.w(TAG, "Unable to update from " + oldPkg.name 8445 + " to " + newPkg.packageName 8446 + ": old package still exists"); 8447 return false; 8448 } 8449 return true; 8450 } 8451 8452 void removeCodePathLI(File codePath) { 8453 if (codePath.isDirectory()) { 8454 try { 8455 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 8456 } catch (InstallerException e) { 8457 Slog.w(TAG, "Failed to remove code path", e); 8458 } 8459 } else { 8460 codePath.delete(); 8461 } 8462 } 8463 8464 private int[] resolveUserIds(int userId) { 8465 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 8466 } 8467 8468 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 8469 if (pkg == null) { 8470 Slog.wtf(TAG, "Package was null!", new Throwable()); 8471 return; 8472 } 8473 clearAppDataLeafLIF(pkg, userId, flags); 8474 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8475 for (int i = 0; i < childCount; i++) { 8476 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 8477 } 8478 } 8479 8480 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 8481 final PackageSetting ps; 8482 synchronized (mPackages) { 8483 ps = mSettings.mPackages.get(pkg.packageName); 8484 } 8485 for (int realUserId : resolveUserIds(userId)) { 8486 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 8487 try { 8488 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 8489 ceDataInode); 8490 } catch (InstallerException e) { 8491 Slog.w(TAG, String.valueOf(e)); 8492 } 8493 } 8494 } 8495 8496 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 8497 if (pkg == null) { 8498 Slog.wtf(TAG, "Package was null!", new Throwable()); 8499 return; 8500 } 8501 destroyAppDataLeafLIF(pkg, userId, flags); 8502 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8503 for (int i = 0; i < childCount; i++) { 8504 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 8505 } 8506 } 8507 8508 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 8509 final PackageSetting ps; 8510 synchronized (mPackages) { 8511 ps = mSettings.mPackages.get(pkg.packageName); 8512 } 8513 for (int realUserId : resolveUserIds(userId)) { 8514 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 8515 try { 8516 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 8517 ceDataInode); 8518 } catch (InstallerException e) { 8519 Slog.w(TAG, String.valueOf(e)); 8520 } 8521 } 8522 } 8523 8524 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 8525 if (pkg == null) { 8526 Slog.wtf(TAG, "Package was null!", new Throwable()); 8527 return; 8528 } 8529 destroyAppProfilesLeafLIF(pkg); 8530 destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */); 8531 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8532 for (int i = 0; i < childCount; i++) { 8533 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 8534 destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId, 8535 true /* removeBaseMarker */); 8536 } 8537 } 8538 8539 private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, 8540 boolean removeBaseMarker) { 8541 if (pkg.isForwardLocked()) { 8542 return; 8543 } 8544 8545 for (String path : pkg.getAllCodePathsExcludingResourceOnly()) { 8546 try { 8547 path = PackageManagerServiceUtils.realpath(new File(path)); 8548 } catch (IOException e) { 8549 // TODO: Should we return early here ? 8550 Slog.w(TAG, "Failed to get canonical path", e); 8551 continue; 8552 } 8553 8554 final String useMarker = path.replace('/', '@'); 8555 for (int realUserId : resolveUserIds(userId)) { 8556 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId); 8557 if (removeBaseMarker) { 8558 File foreignUseMark = new File(profileDir, useMarker); 8559 if (foreignUseMark.exists()) { 8560 if (!foreignUseMark.delete()) { 8561 Slog.w(TAG, "Unable to delete foreign user mark for package: " 8562 + pkg.packageName); 8563 } 8564 } 8565 } 8566 8567 File[] markers = profileDir.listFiles(); 8568 if (markers != null) { 8569 final String searchString = "@" + pkg.packageName + "@"; 8570 // We also delete all markers that contain the package name we're 8571 // uninstalling. These are associated with secondary dex-files belonging 8572 // to the package. Reconstructing the path of these dex files is messy 8573 // in general. 8574 for (File marker : markers) { 8575 if (marker.getName().indexOf(searchString) > 0) { 8576 if (!marker.delete()) { 8577 Slog.w(TAG, "Unable to delete foreign user mark for package: " 8578 + pkg.packageName); 8579 } 8580 } 8581 } 8582 } 8583 } 8584 } 8585 } 8586 8587 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 8588 try { 8589 mInstaller.destroyAppProfiles(pkg.packageName); 8590 } catch (InstallerException e) { 8591 Slog.w(TAG, String.valueOf(e)); 8592 } 8593 } 8594 8595 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 8596 if (pkg == null) { 8597 Slog.wtf(TAG, "Package was null!", new Throwable()); 8598 return; 8599 } 8600 clearAppProfilesLeafLIF(pkg); 8601 // We don't remove the base foreign use marker when clearing profiles because 8602 // we will rename it when the app is updated. Unlike the actual profile contents, 8603 // the foreign use marker is good across installs. 8604 destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */); 8605 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8606 for (int i = 0; i < childCount; i++) { 8607 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 8608 } 8609 } 8610 8611 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 8612 try { 8613 mInstaller.clearAppProfiles(pkg.packageName); 8614 } catch (InstallerException e) { 8615 Slog.w(TAG, String.valueOf(e)); 8616 } 8617 } 8618 8619 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 8620 long lastUpdateTime) { 8621 // Set parent install/update time 8622 PackageSetting ps = (PackageSetting) pkg.mExtras; 8623 if (ps != null) { 8624 ps.firstInstallTime = firstInstallTime; 8625 ps.lastUpdateTime = lastUpdateTime; 8626 } 8627 // Set children install/update time 8628 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8629 for (int i = 0; i < childCount; i++) { 8630 PackageParser.Package childPkg = pkg.childPackages.get(i); 8631 ps = (PackageSetting) childPkg.mExtras; 8632 if (ps != null) { 8633 ps.firstInstallTime = firstInstallTime; 8634 ps.lastUpdateTime = lastUpdateTime; 8635 } 8636 } 8637 } 8638 8639 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 8640 PackageParser.Package changingLib) { 8641 if (file.path != null) { 8642 usesLibraryFiles.add(file.path); 8643 return; 8644 } 8645 PackageParser.Package p = mPackages.get(file.apk); 8646 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 8647 // If we are doing this while in the middle of updating a library apk, 8648 // then we need to make sure to use that new apk for determining the 8649 // dependencies here. (We haven't yet finished committing the new apk 8650 // to the package manager state.) 8651 if (p == null || p.packageName.equals(changingLib.packageName)) { 8652 p = changingLib; 8653 } 8654 } 8655 if (p != null) { 8656 usesLibraryFiles.addAll(p.getAllCodePaths()); 8657 } 8658 } 8659 8660 private void updateSharedLibrariesLPr(PackageParser.Package pkg, 8661 PackageParser.Package changingLib) throws PackageManagerException { 8662 if (pkg == null) { 8663 return; 8664 } 8665 ArraySet<String> usesLibraryFiles = null; 8666 if (pkg.usesLibraries != null) { 8667 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries, 8668 null, null, pkg.packageName, changingLib, true, null); 8669 } 8670 if (pkg.usesStaticLibraries != null) { 8671 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries, 8672 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests, 8673 pkg.packageName, changingLib, true, usesLibraryFiles); 8674 } 8675 if (pkg.usesOptionalLibraries != null) { 8676 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries, 8677 null, null, pkg.packageName, changingLib, false, usesLibraryFiles); 8678 } 8679 if (!ArrayUtils.isEmpty(usesLibraryFiles)) { 8680 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]); 8681 } else { 8682 pkg.usesLibraryFiles = null; 8683 } 8684 } 8685 8686 private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries, 8687 @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests, 8688 @NonNull String packageName, @Nullable PackageParser.Package changingLib, 8689 boolean required, @Nullable ArraySet<String> outUsedLibraries) 8690 throws PackageManagerException { 8691 final int libCount = requestedLibraries.size(); 8692 for (int i = 0; i < libCount; i++) { 8693 final String libName = requestedLibraries.get(i); 8694 final int libVersion = requiredVersions != null ? requiredVersions[i] 8695 : SharedLibraryInfo.VERSION_UNDEFINED; 8696 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion); 8697 if (libEntry == null) { 8698 if (required) { 8699 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8700 "Package " + packageName + " requires unavailable shared library " 8701 + libName + "; failing!"); 8702 } else { 8703 Slog.w(TAG, "Package " + packageName 8704 + " desires unavailable shared library " 8705 + libName + "; ignoring!"); 8706 } 8707 } else { 8708 if (requiredVersions != null && requiredCertDigests != null) { 8709 if (libEntry.info.getVersion() != requiredVersions[i]) { 8710 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8711 "Package " + packageName + " requires unavailable static shared" 8712 + " library " + libName + " version " 8713 + libEntry.info.getVersion() + "; failing!"); 8714 } 8715 8716 PackageParser.Package libPkg = mPackages.get(libEntry.apk); 8717 if (libPkg == null) { 8718 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8719 "Package " + packageName + " requires unavailable static shared" 8720 + " library; failing!"); 8721 } 8722 8723 String expectedCertDigest = requiredCertDigests[i]; 8724 String libCertDigest = PackageUtils.computeCertSha256Digest( 8725 libPkg.mSignatures[0]); 8726 if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) { 8727 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8728 "Package " + packageName + " requires differently signed" + 8729 " static shared library; failing!"); 8730 } 8731 } 8732 8733 if (outUsedLibraries == null) { 8734 outUsedLibraries = new ArraySet<>(); 8735 } 8736 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib); 8737 } 8738 } 8739 return outUsedLibraries; 8740 } 8741 8742 private static boolean hasString(List<String> list, List<String> which) { 8743 if (list == null) { 8744 return false; 8745 } 8746 for (int i=list.size()-1; i>=0; i--) { 8747 for (int j=which.size()-1; j>=0; j--) { 8748 if (which.get(j).equals(list.get(i))) { 8749 return true; 8750 } 8751 } 8752 } 8753 return false; 8754 } 8755 8756 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 8757 PackageParser.Package changingPkg) { 8758 ArrayList<PackageParser.Package> res = null; 8759 for (PackageParser.Package pkg : mPackages.values()) { 8760 if (changingPkg != null 8761 && !hasString(pkg.usesLibraries, changingPkg.libraryNames) 8762 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames) 8763 && !ArrayUtils.contains(pkg.usesStaticLibraries, 8764 changingPkg.staticSharedLibName)) { 8765 return null; 8766 } 8767 if (res == null) { 8768 res = new ArrayList<>(); 8769 } 8770 res.add(pkg); 8771 try { 8772 updateSharedLibrariesLPr(pkg, changingPkg); 8773 } catch (PackageManagerException e) { 8774 // If a system app update or an app and a required lib missing we 8775 // delete the package and for updated system apps keep the data as 8776 // it is better for the user to reinstall than to be in an limbo 8777 // state. Also libs disappearing under an app should never happen 8778 // - just in case. 8779 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) { 8780 final int flags = pkg.isUpdatedSystemApp() 8781 ? PackageManager.DELETE_KEEP_DATA : 0; 8782 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(), 8783 flags , null, true, null); 8784 } 8785 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 8786 } 8787 } 8788 return res; 8789 } 8790 8791 /** 8792 * Derive the value of the {@code cpuAbiOverride} based on the provided 8793 * value and an optional stored value from the package settings. 8794 */ 8795 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 8796 String cpuAbiOverride = null; 8797 8798 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 8799 cpuAbiOverride = null; 8800 } else if (abiOverride != null) { 8801 cpuAbiOverride = abiOverride; 8802 } else if (settings != null) { 8803 cpuAbiOverride = settings.cpuAbiOverrideString; 8804 } 8805 8806 return cpuAbiOverride; 8807 } 8808 8809 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 8810 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 8811 throws PackageManagerException { 8812 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 8813 // If the package has children and this is the first dive in the function 8814 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 8815 // whether all packages (parent and children) would be successfully scanned 8816 // before the actual scan since scanning mutates internal state and we want 8817 // to atomically install the package and its children. 8818 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8819 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 8820 scanFlags |= SCAN_CHECK_ONLY; 8821 } 8822 } else { 8823 scanFlags &= ~SCAN_CHECK_ONLY; 8824 } 8825 8826 final PackageParser.Package scannedPkg; 8827 try { 8828 // Scan the parent 8829 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 8830 // Scan the children 8831 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8832 for (int i = 0; i < childCount; i++) { 8833 PackageParser.Package childPkg = pkg.childPackages.get(i); 8834 scanPackageLI(childPkg, policyFlags, 8835 scanFlags, currentTime, user); 8836 } 8837 } finally { 8838 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8839 } 8840 8841 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8842 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 8843 } 8844 8845 return scannedPkg; 8846 } 8847 8848 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 8849 int scanFlags, long currentTime, @Nullable UserHandle user) 8850 throws PackageManagerException { 8851 boolean success = false; 8852 try { 8853 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 8854 currentTime, user); 8855 success = true; 8856 return res; 8857 } finally { 8858 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 8859 // DELETE_DATA_ON_FAILURES is only used by frozen paths 8860 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 8861 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 8862 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 8863 } 8864 } 8865 } 8866 8867 /** 8868 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 8869 */ 8870 private static boolean apkHasCode(String fileName) { 8871 StrictJarFile jarFile = null; 8872 try { 8873 jarFile = new StrictJarFile(fileName, 8874 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 8875 return jarFile.findEntry("classes.dex") != null; 8876 } catch (IOException ignore) { 8877 } finally { 8878 try { 8879 if (jarFile != null) { 8880 jarFile.close(); 8881 } 8882 } catch (IOException ignore) {} 8883 } 8884 return false; 8885 } 8886 8887 /** 8888 * Enforces code policy for the package. This ensures that if an APK has 8889 * declared hasCode="true" in its manifest that the APK actually contains 8890 * code. 8891 * 8892 * @throws PackageManagerException If bytecode could not be found when it should exist 8893 */ 8894 private static void assertCodePolicy(PackageParser.Package pkg) 8895 throws PackageManagerException { 8896 final boolean shouldHaveCode = 8897 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 8898 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 8899 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8900 "Package " + pkg.baseCodePath + " code is missing"); 8901 } 8902 8903 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 8904 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 8905 final boolean splitShouldHaveCode = 8906 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 8907 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 8908 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8909 "Package " + pkg.splitCodePaths[i] + " code is missing"); 8910 } 8911 } 8912 } 8913 } 8914 8915 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 8916 final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user) 8917 throws PackageManagerException { 8918 if (DEBUG_PACKAGE_SCANNING) { 8919 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8920 Log.d(TAG, "Scanning package " + pkg.packageName); 8921 } 8922 8923 applyPolicy(pkg, policyFlags); 8924 8925 assertPackageIsValid(pkg, policyFlags, scanFlags); 8926 8927 // Initialize package source and resource directories 8928 final File scanFile = new File(pkg.codePath); 8929 final File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 8930 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 8931 8932 SharedUserSetting suid = null; 8933 PackageSetting pkgSetting = null; 8934 8935 // Getting the package setting may have a side-effect, so if we 8936 // are only checking if scan would succeed, stash a copy of the 8937 // old setting to restore at the end. 8938 PackageSetting nonMutatedPs = null; 8939 8940 // We keep references to the derived CPU Abis from settings in oder to reuse 8941 // them in the case where we're not upgrading or booting for the first time. 8942 String primaryCpuAbiFromSettings = null; 8943 String secondaryCpuAbiFromSettings = null; 8944 8945 // writer 8946 synchronized (mPackages) { 8947 if (pkg.mSharedUserId != null) { 8948 // SIDE EFFECTS; may potentially allocate a new shared user 8949 suid = mSettings.getSharedUserLPw( 8950 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); 8951 if (DEBUG_PACKAGE_SCANNING) { 8952 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8953 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 8954 + "): packages=" + suid.packages); 8955 } 8956 } 8957 8958 // Check if we are renaming from an original package name. 8959 PackageSetting origPackage = null; 8960 String realName = null; 8961 if (pkg.mOriginalPackages != null) { 8962 // This package may need to be renamed to a previously 8963 // installed name. Let's check on that... 8964 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage); 8965 if (pkg.mOriginalPackages.contains(renamed)) { 8966 // This package had originally been installed as the 8967 // original name, and we have already taken care of 8968 // transitioning to the new one. Just update the new 8969 // one to continue using the old name. 8970 realName = pkg.mRealPackage; 8971 if (!pkg.packageName.equals(renamed)) { 8972 // Callers into this function may have already taken 8973 // care of renaming the package; only do it here if 8974 // it is not already done. 8975 pkg.setPackageName(renamed); 8976 } 8977 } else { 8978 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 8979 if ((origPackage = mSettings.getPackageLPr( 8980 pkg.mOriginalPackages.get(i))) != null) { 8981 // We do have the package already installed under its 8982 // original name... should we use it? 8983 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 8984 // New package is not compatible with original. 8985 origPackage = null; 8986 continue; 8987 } else if (origPackage.sharedUser != null) { 8988 // Make sure uid is compatible between packages. 8989 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 8990 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 8991 + " to " + pkg.packageName + ": old uid " 8992 + origPackage.sharedUser.name 8993 + " differs from " + pkg.mSharedUserId); 8994 origPackage = null; 8995 continue; 8996 } 8997 // TODO: Add case when shared user id is added [b/28144775] 8998 } else { 8999 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 9000 + pkg.packageName + " to old name " + origPackage.name); 9001 } 9002 break; 9003 } 9004 } 9005 } 9006 } 9007 9008 if (mTransferedPackages.contains(pkg.packageName)) { 9009 Slog.w(TAG, "Package " + pkg.packageName 9010 + " was transferred to another, but its .apk remains"); 9011 } 9012 9013 // See comments in nonMutatedPs declaration 9014 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 9015 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 9016 if (foundPs != null) { 9017 nonMutatedPs = new PackageSetting(foundPs); 9018 } 9019 } 9020 9021 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) { 9022 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 9023 if (foundPs != null) { 9024 primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString; 9025 secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString; 9026 } 9027 } 9028 9029 pkgSetting = mSettings.getPackageLPr(pkg.packageName); 9030 if (pkgSetting != null && pkgSetting.sharedUser != suid) { 9031 PackageManagerService.reportSettingsProblem(Log.WARN, 9032 "Package " + pkg.packageName + " shared user changed from " 9033 + (pkgSetting.sharedUser != null 9034 ? pkgSetting.sharedUser.name : "<nothing>") 9035 + " to " 9036 + (suid != null ? suid.name : "<nothing>") 9037 + "; replacing with new"); 9038 pkgSetting = null; 9039 } 9040 final PackageSetting oldPkgSetting = 9041 pkgSetting == null ? null : new PackageSetting(pkgSetting); 9042 final PackageSetting disabledPkgSetting = 9043 mSettings.getDisabledSystemPkgLPr(pkg.packageName); 9044 9045 String[] usesStaticLibraries = null; 9046 if (pkg.usesStaticLibraries != null) { 9047 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()]; 9048 pkg.usesStaticLibraries.toArray(usesStaticLibraries); 9049 } 9050 9051 if (pkgSetting == null) { 9052 final String parentPackageName = (pkg.parentPackage != null) 9053 ? pkg.parentPackage.packageName : null; 9054 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 9055 // REMOVE SharedUserSetting from method; update in a separate call 9056 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage, 9057 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile, 9058 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi, 9059 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode, 9060 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user, 9061 true /*allowInstall*/, instantApp, parentPackageName, 9062 pkg.getChildPackageNames(), UserManagerService.getInstance(), 9063 usesStaticLibraries, pkg.usesStaticLibrariesVersions); 9064 // SIDE EFFECTS; updates system state; move elsewhere 9065 if (origPackage != null) { 9066 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name); 9067 } 9068 mSettings.addUserToSettingLPw(pkgSetting); 9069 } else { 9070 // REMOVE SharedUserSetting from method; update in a separate call. 9071 // 9072 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi, 9073 // secondaryCpuAbi are not known at this point so we always update them 9074 // to null here, only to reset them at a later point. 9075 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile, 9076 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi, 9077 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags, 9078 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(), 9079 UserManagerService.getInstance(), usesStaticLibraries, 9080 pkg.usesStaticLibrariesVersions); 9081 } 9082 // SIDE EFFECTS; persists system state to files on disk; move elsewhere 9083 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); 9084 9085 // SIDE EFFECTS; modifies system state; move elsewhere 9086 if (pkgSetting.origPackage != null) { 9087 // If we are first transitioning from an original package, 9088 // fix up the new package's name now. We need to do this after 9089 // looking up the package under its new name, so getPackageLP 9090 // can take care of fiddling things correctly. 9091 pkg.setPackageName(origPackage.name); 9092 9093 // File a report about this. 9094 String msg = "New package " + pkgSetting.realName 9095 + " renamed to replace old package " + pkgSetting.name; 9096 reportSettingsProblem(Log.WARN, msg); 9097 9098 // Make a note of it. 9099 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 9100 mTransferedPackages.add(origPackage.name); 9101 } 9102 9103 // No longer need to retain this. 9104 pkgSetting.origPackage = null; 9105 } 9106 9107 // SIDE EFFECTS; modifies system state; move elsewhere 9108 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 9109 // Make a note of it. 9110 mTransferedPackages.add(pkg.packageName); 9111 } 9112 9113 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 9114 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 9115 } 9116 9117 if ((scanFlags & SCAN_BOOTING) == 0 9118 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9119 // Check all shared libraries and map to their actual file path. 9120 // We only do this here for apps not on a system dir, because those 9121 // are the only ones that can fail an install due to this. We 9122 // will take care of the system apps by updating all of their 9123 // library paths after the scan is done. Also during the initial 9124 // scan don't update any libs as we do this wholesale after all 9125 // apps are scanned to avoid dependency based scanning. 9126 updateSharedLibrariesLPr(pkg, null); 9127 } 9128 9129 if (mFoundPolicyFile) { 9130 SELinuxMMAC.assignSeInfoValue(pkg); 9131 } 9132 pkg.applicationInfo.uid = pkgSetting.appId; 9133 pkg.mExtras = pkgSetting; 9134 9135 9136 // Static shared libs have same package with different versions where 9137 // we internally use a synthetic package name to allow multiple versions 9138 // of the same package, therefore we need to compare signatures against 9139 // the package setting for the latest library version. 9140 PackageSetting signatureCheckPs = pkgSetting; 9141 if (pkg.applicationInfo.isStaticSharedLibrary()) { 9142 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg); 9143 if (libraryEntry != null) { 9144 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk); 9145 } 9146 } 9147 9148 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) { 9149 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) { 9150 // We just determined the app is signed correctly, so bring 9151 // over the latest parsed certs. 9152 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9153 } else { 9154 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9155 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 9156 "Package " + pkg.packageName + " upgrade keys do not match the " 9157 + "previously installed version"); 9158 } else { 9159 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9160 String msg = "System package " + pkg.packageName 9161 + " signature changed; retaining data."; 9162 reportSettingsProblem(Log.WARN, msg); 9163 } 9164 } 9165 } else { 9166 try { 9167 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService 9168 verifySignaturesLP(signatureCheckPs, pkg); 9169 // We just determined the app is signed correctly, so bring 9170 // over the latest parsed certs. 9171 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9172 } catch (PackageManagerException e) { 9173 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9174 throw e; 9175 } 9176 // The signature has changed, but this package is in the system 9177 // image... let's recover! 9178 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9179 // However... if this package is part of a shared user, but it 9180 // doesn't match the signature of the shared user, let's fail. 9181 // What this means is that you can't change the signatures 9182 // associated with an overall shared user, which doesn't seem all 9183 // that unreasonable. 9184 if (signatureCheckPs.sharedUser != null) { 9185 if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures, 9186 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 9187 throw new PackageManagerException( 9188 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 9189 "Signature mismatch for shared user: " 9190 + pkgSetting.sharedUser); 9191 } 9192 } 9193 // File a report about this. 9194 String msg = "System package " + pkg.packageName 9195 + " signature changed; retaining data."; 9196 reportSettingsProblem(Log.WARN, msg); 9197 } 9198 } 9199 9200 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 9201 // This package wants to adopt ownership of permissions from 9202 // another package. 9203 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 9204 final String origName = pkg.mAdoptPermissions.get(i); 9205 final PackageSetting orig = mSettings.getPackageLPr(origName); 9206 if (orig != null) { 9207 if (verifyPackageUpdateLPr(orig, pkg)) { 9208 Slog.i(TAG, "Adopting permissions from " + origName + " to " 9209 + pkg.packageName); 9210 // SIDE EFFECTS; updates permissions system state; move elsewhere 9211 mSettings.transferPermissionsLPw(origName, pkg.packageName); 9212 } 9213 } 9214 } 9215 } 9216 } 9217 9218 pkg.applicationInfo.processName = fixProcessName( 9219 pkg.applicationInfo.packageName, 9220 pkg.applicationInfo.processName); 9221 9222 if (pkg != mPlatformPackage) { 9223 // Get all of our default paths setup 9224 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 9225 } 9226 9227 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 9228 9229 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 9230 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) { 9231 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); 9232 derivePackageAbi( 9233 pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir); 9234 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9235 9236 // Some system apps still use directory structure for native libraries 9237 // in which case we might end up not detecting abi solely based on apk 9238 // structure. Try to detect abi based on directory structure. 9239 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 9240 pkg.applicationInfo.primaryCpuAbi == null) { 9241 setBundledAppAbisAndRoots(pkg, pkgSetting); 9242 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9243 } 9244 } else { 9245 // This is not a first boot or an upgrade, don't bother deriving the 9246 // ABI during the scan. Instead, trust the value that was stored in the 9247 // package setting. 9248 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; 9249 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings; 9250 9251 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9252 9253 if (DEBUG_ABI_SELECTION) { 9254 Slog.i(TAG, "Using ABIS and native lib paths from settings : " + 9255 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " + 9256 pkg.applicationInfo.secondaryCpuAbi); 9257 } 9258 } 9259 } else { 9260 if ((scanFlags & SCAN_MOVE) != 0) { 9261 // We haven't run dex-opt for this move (since we've moved the compiled output too) 9262 // but we already have this packages package info in the PackageSetting. We just 9263 // use that and derive the native library path based on the new codepath. 9264 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 9265 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 9266 } 9267 9268 // Set native library paths again. For moves, the path will be updated based on the 9269 // ABIs we've determined above. For non-moves, the path will be updated based on the 9270 // ABIs we determined during compilation, but the path will depend on the final 9271 // package path (after the rename away from the stage path). 9272 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9273 } 9274 9275 // This is a special case for the "system" package, where the ABI is 9276 // dictated by the zygote configuration (and init.rc). We should keep track 9277 // of this ABI so that we can deal with "normal" applications that run under 9278 // the same UID correctly. 9279 if (mPlatformPackage == pkg) { 9280 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 9281 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 9282 } 9283 9284 // If there's a mismatch between the abi-override in the package setting 9285 // and the abiOverride specified for the install. Warn about this because we 9286 // would've already compiled the app without taking the package setting into 9287 // account. 9288 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 9289 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 9290 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 9291 " for package " + pkg.packageName); 9292 } 9293 } 9294 9295 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9296 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9297 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 9298 9299 // Copy the derived override back to the parsed package, so that we can 9300 // update the package settings accordingly. 9301 pkg.cpuAbiOverride = cpuAbiOverride; 9302 9303 if (DEBUG_ABI_SELECTION) { 9304 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 9305 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 9306 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 9307 } 9308 9309 // Push the derived path down into PackageSettings so we know what to 9310 // clean up at uninstall time. 9311 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 9312 9313 if (DEBUG_ABI_SELECTION) { 9314 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 9315 " primary=" + pkg.applicationInfo.primaryCpuAbi + 9316 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 9317 } 9318 9319 // SIDE EFFECTS; removes DEX files from disk; move elsewhere 9320 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 9321 // We don't do this here during boot because we can do it all 9322 // at once after scanning all existing packages. 9323 // 9324 // We also do this *before* we perform dexopt on this package, so that 9325 // we can avoid redundant dexopts, and also to make sure we've got the 9326 // code and package path correct. 9327 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg); 9328 } 9329 9330 if (mFactoryTest && pkg.requestedPermissions.contains( 9331 android.Manifest.permission.FACTORY_TEST)) { 9332 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 9333 } 9334 9335 if (isSystemApp(pkg)) { 9336 pkgSetting.isOrphaned = true; 9337 } 9338 9339 // Take care of first install / last update times. 9340 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 9341 if (currentTime != 0) { 9342 if (pkgSetting.firstInstallTime == 0) { 9343 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 9344 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) { 9345 pkgSetting.lastUpdateTime = currentTime; 9346 } 9347 } else if (pkgSetting.firstInstallTime == 0) { 9348 // We need *something*. Take time time stamp of the file. 9349 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 9350 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 9351 if (scanFileTime != pkgSetting.timeStamp) { 9352 // A package on the system image has changed; consider this 9353 // to be an update. 9354 pkgSetting.lastUpdateTime = scanFileTime; 9355 } 9356 } 9357 pkgSetting.setTimeStamp(scanFileTime); 9358 9359 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 9360 if (nonMutatedPs != null) { 9361 synchronized (mPackages) { 9362 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 9363 } 9364 } 9365 } else { 9366 final int userId = user == null ? 0 : user.getIdentifier(); 9367 // Modify state for the given package setting 9368 commitPackageSettings(pkg, pkgSetting, user, scanFlags, 9369 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/); 9370 if (pkgSetting.getInstantApp(userId)) { 9371 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId); 9372 } 9373 } 9374 return pkg; 9375 } 9376 9377 /** 9378 * Applies policy to the parsed package based upon the given policy flags. 9379 * Ensures the package is in a good state. 9380 * <p> 9381 * Implementation detail: This method must NOT have any side effect. It would 9382 * ideally be static, but, it requires locks to read system state. 9383 */ 9384 private void applyPolicy(PackageParser.Package pkg, int policyFlags) { 9385 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 9386 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 9387 if (pkg.applicationInfo.isDirectBootAware()) { 9388 // we're direct boot aware; set for all components 9389 for (PackageParser.Service s : pkg.services) { 9390 s.info.encryptionAware = s.info.directBootAware = true; 9391 } 9392 for (PackageParser.Provider p : pkg.providers) { 9393 p.info.encryptionAware = p.info.directBootAware = true; 9394 } 9395 for (PackageParser.Activity a : pkg.activities) { 9396 a.info.encryptionAware = a.info.directBootAware = true; 9397 } 9398 for (PackageParser.Activity r : pkg.receivers) { 9399 r.info.encryptionAware = r.info.directBootAware = true; 9400 } 9401 } 9402 } else { 9403 // Only allow system apps to be flagged as core apps. 9404 pkg.coreApp = false; 9405 // clear flags not applicable to regular apps 9406 pkg.applicationInfo.privateFlags &= 9407 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 9408 pkg.applicationInfo.privateFlags &= 9409 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 9410 } 9411 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 9412 9413 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 9414 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 9415 } 9416 9417 if (!isSystemApp(pkg)) { 9418 // Only system apps can use these features. 9419 pkg.mOriginalPackages = null; 9420 pkg.mRealPackage = null; 9421 pkg.mAdoptPermissions = null; 9422 } 9423 } 9424 9425 /** 9426 * Asserts the parsed package is valid according to the given policy. If the 9427 * package is invalid, for whatever reason, throws {@link PackgeManagerException}. 9428 * <p> 9429 * Implementation detail: This method must NOT have any side effects. It would 9430 * ideally be static, but, it requires locks to read system state. 9431 * 9432 * @throws PackageManagerException If the package fails any of the validation checks 9433 */ 9434 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags) 9435 throws PackageManagerException { 9436 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 9437 assertCodePolicy(pkg); 9438 } 9439 9440 if (pkg.applicationInfo.getCodePath() == null || 9441 pkg.applicationInfo.getResourcePath() == null) { 9442 // Bail out. The resource and code paths haven't been set. 9443 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 9444 "Code and resource paths haven't been set correctly"); 9445 } 9446 9447 // Make sure we're not adding any bogus keyset info 9448 KeySetManagerService ksms = mSettings.mKeySetManagerService; 9449 ksms.assertScannedPackageValid(pkg); 9450 9451 synchronized (mPackages) { 9452 // The special "android" package can only be defined once 9453 if (pkg.packageName.equals("android")) { 9454 if (mAndroidApplication != null) { 9455 Slog.w(TAG, "*************************************************"); 9456 Slog.w(TAG, "Core android package being redefined. Skipping."); 9457 Slog.w(TAG, " codePath=" + pkg.codePath); 9458 Slog.w(TAG, "*************************************************"); 9459 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 9460 "Core android package being redefined. Skipping."); 9461 } 9462 } 9463 9464 // A package name must be unique; don't allow duplicates 9465 if (mPackages.containsKey(pkg.packageName)) { 9466 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 9467 "Application package " + pkg.packageName 9468 + " already installed. Skipping duplicate."); 9469 } 9470 9471 if (pkg.applicationInfo.isStaticSharedLibrary()) { 9472 // Static libs have a synthetic package name containing the version 9473 // but we still want the base name to be unique. 9474 if (mPackages.containsKey(pkg.manifestPackageName)) { 9475 throw new PackageManagerException( 9476 "Duplicate static shared lib provider package"); 9477 } 9478 9479 // Static shared libraries should have at least O target SDK 9480 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) { 9481 throw new PackageManagerException( 9482 "Packages declaring static-shared libs must target O SDK or higher"); 9483 } 9484 9485 // Package declaring static a shared lib cannot be instant apps 9486 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 9487 throw new PackageManagerException( 9488 "Packages declaring static-shared libs cannot be instant apps"); 9489 } 9490 9491 // Package declaring static a shared lib cannot be renamed since the package 9492 // name is synthetic and apps can't code around package manager internals. 9493 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) { 9494 throw new PackageManagerException( 9495 "Packages declaring static-shared libs cannot be renamed"); 9496 } 9497 9498 // Package declaring static a shared lib cannot declare child packages 9499 if (!ArrayUtils.isEmpty(pkg.childPackages)) { 9500 throw new PackageManagerException( 9501 "Packages declaring static-shared libs cannot have child packages"); 9502 } 9503 9504 // Package declaring static a shared lib cannot declare dynamic libs 9505 if (!ArrayUtils.isEmpty(pkg.libraryNames)) { 9506 throw new PackageManagerException( 9507 "Packages declaring static-shared libs cannot declare dynamic libs"); 9508 } 9509 9510 // Package declaring static a shared lib cannot declare shared users 9511 if (pkg.mSharedUserId != null) { 9512 throw new PackageManagerException( 9513 "Packages declaring static-shared libs cannot declare shared users"); 9514 } 9515 9516 // Static shared libs cannot declare activities 9517 if (!pkg.activities.isEmpty()) { 9518 throw new PackageManagerException( 9519 "Static shared libs cannot declare activities"); 9520 } 9521 9522 // Static shared libs cannot declare services 9523 if (!pkg.services.isEmpty()) { 9524 throw new PackageManagerException( 9525 "Static shared libs cannot declare services"); 9526 } 9527 9528 // Static shared libs cannot declare providers 9529 if (!pkg.providers.isEmpty()) { 9530 throw new PackageManagerException( 9531 "Static shared libs cannot declare content providers"); 9532 } 9533 9534 // Static shared libs cannot declare receivers 9535 if (!pkg.receivers.isEmpty()) { 9536 throw new PackageManagerException( 9537 "Static shared libs cannot declare broadcast receivers"); 9538 } 9539 9540 // Static shared libs cannot declare permission groups 9541 if (!pkg.permissionGroups.isEmpty()) { 9542 throw new PackageManagerException( 9543 "Static shared libs cannot declare permission groups"); 9544 } 9545 9546 // Static shared libs cannot declare permissions 9547 if (!pkg.permissions.isEmpty()) { 9548 throw new PackageManagerException( 9549 "Static shared libs cannot declare permissions"); 9550 } 9551 9552 // Static shared libs cannot declare protected broadcasts 9553 if (pkg.protectedBroadcasts != null) { 9554 throw new PackageManagerException( 9555 "Static shared libs cannot declare protected broadcasts"); 9556 } 9557 9558 // Static shared libs cannot be overlay targets 9559 if (pkg.mOverlayTarget != null) { 9560 throw new PackageManagerException( 9561 "Static shared libs cannot be overlay targets"); 9562 } 9563 9564 // The version codes must be ordered as lib versions 9565 int minVersionCode = Integer.MIN_VALUE; 9566 int maxVersionCode = Integer.MAX_VALUE; 9567 9568 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get( 9569 pkg.staticSharedLibName); 9570 if (versionedLib != null) { 9571 final int versionCount = versionedLib.size(); 9572 for (int i = 0; i < versionCount; i++) { 9573 SharedLibraryInfo libInfo = versionedLib.valueAt(i).info; 9574 // TODO: We will change version code to long, so in the new API it is long 9575 final int libVersionCode = (int) libInfo.getDeclaringPackage() 9576 .getVersionCode(); 9577 if (libInfo.getVersion() < pkg.staticSharedLibVersion) { 9578 minVersionCode = Math.max(minVersionCode, libVersionCode + 1); 9579 } else if (libInfo.getVersion() > pkg.staticSharedLibVersion) { 9580 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1); 9581 } else { 9582 minVersionCode = maxVersionCode = libVersionCode; 9583 break; 9584 } 9585 } 9586 } 9587 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) { 9588 throw new PackageManagerException("Static shared" 9589 + " lib version codes must be ordered as lib versions"); 9590 } 9591 } 9592 9593 // Only privileged apps and updated privileged apps can add child packages. 9594 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 9595 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 9596 throw new PackageManagerException("Only privileged apps can add child " 9597 + "packages. Ignoring package " + pkg.packageName); 9598 } 9599 final int childCount = pkg.childPackages.size(); 9600 for (int i = 0; i < childCount; i++) { 9601 PackageParser.Package childPkg = pkg.childPackages.get(i); 9602 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 9603 childPkg.packageName)) { 9604 throw new PackageManagerException("Can't override child of " 9605 + "another disabled app. Ignoring package " + pkg.packageName); 9606 } 9607 } 9608 } 9609 9610 // If we're only installing presumed-existing packages, require that the 9611 // scanned APK is both already known and at the path previously established 9612 // for it. Previously unknown packages we pick up normally, but if we have an 9613 // a priori expectation about this package's install presence, enforce it. 9614 // With a singular exception for new system packages. When an OTA contains 9615 // a new system package, we allow the codepath to change from a system location 9616 // to the user-installed location. If we don't allow this change, any newer, 9617 // user-installed version of the application will be ignored. 9618 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 9619 if (mExpectingBetter.containsKey(pkg.packageName)) { 9620 logCriticalInfo(Log.WARN, 9621 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 9622 } else { 9623 PackageSetting known = mSettings.getPackageLPr(pkg.packageName); 9624 if (known != null) { 9625 if (DEBUG_PACKAGE_SCANNING) { 9626 Log.d(TAG, "Examining " + pkg.codePath 9627 + " and requiring known paths " + known.codePathString 9628 + " & " + known.resourcePathString); 9629 } 9630 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 9631 || !pkg.applicationInfo.getResourcePath().equals( 9632 known.resourcePathString)) { 9633 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 9634 "Application package " + pkg.packageName 9635 + " found at " + pkg.applicationInfo.getCodePath() 9636 + " but expected at " + known.codePathString 9637 + "; ignoring."); 9638 } 9639 } 9640 } 9641 } 9642 9643 // Verify that this new package doesn't have any content providers 9644 // that conflict with existing packages. Only do this if the 9645 // package isn't already installed, since we don't want to break 9646 // things that are installed. 9647 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 9648 final int N = pkg.providers.size(); 9649 int i; 9650 for (i=0; i<N; i++) { 9651 PackageParser.Provider p = pkg.providers.get(i); 9652 if (p.info.authority != null) { 9653 String names[] = p.info.authority.split(";"); 9654 for (int j = 0; j < names.length; j++) { 9655 if (mProvidersByAuthority.containsKey(names[j])) { 9656 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 9657 final String otherPackageName = 9658 ((other != null && other.getComponentName() != null) ? 9659 other.getComponentName().getPackageName() : "?"); 9660 throw new PackageManagerException( 9661 INSTALL_FAILED_CONFLICTING_PROVIDER, 9662 "Can't install because provider name " + names[j] 9663 + " (in package " + pkg.applicationInfo.packageName 9664 + ") is already used by " + otherPackageName); 9665 } 9666 } 9667 } 9668 } 9669 } 9670 } 9671 } 9672 9673 private boolean addSharedLibraryLPw(String path, String apk, String name, int version, 9674 int type, String declaringPackageName, int declaringVersionCode) { 9675 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 9676 if (versionedLib == null) { 9677 versionedLib = new SparseArray<>(); 9678 mSharedLibraries.put(name, versionedLib); 9679 if (type == SharedLibraryInfo.TYPE_STATIC) { 9680 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib); 9681 } 9682 } else if (versionedLib.indexOfKey(version) >= 0) { 9683 return false; 9684 } 9685 SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name, 9686 version, type, declaringPackageName, declaringVersionCode); 9687 versionedLib.put(version, libEntry); 9688 return true; 9689 } 9690 9691 private boolean removeSharedLibraryLPw(String name, int version) { 9692 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 9693 if (versionedLib == null) { 9694 return false; 9695 } 9696 final int libIdx = versionedLib.indexOfKey(version); 9697 if (libIdx < 0) { 9698 return false; 9699 } 9700 SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx); 9701 versionedLib.remove(version); 9702 if (versionedLib.size() <= 0) { 9703 mSharedLibraries.remove(name); 9704 if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) { 9705 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage() 9706 .getPackageName()); 9707 } 9708 } 9709 return true; 9710 } 9711 9712 /** 9713 * Adds a scanned package to the system. When this method is finished, the package will 9714 * be available for query, resolution, etc... 9715 */ 9716 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting, 9717 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException { 9718 final String pkgName = pkg.packageName; 9719 if (mCustomResolverComponentName != null && 9720 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 9721 setUpCustomResolverActivity(pkg); 9722 } 9723 9724 if (pkg.packageName.equals("android")) { 9725 synchronized (mPackages) { 9726 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 9727 // Set up information for our fall-back user intent resolution activity. 9728 mPlatformPackage = pkg; 9729 pkg.mVersionCode = mSdkVersion; 9730 mAndroidApplication = pkg.applicationInfo; 9731 if (!mResolverReplaced) { 9732 mResolveActivity.applicationInfo = mAndroidApplication; 9733 mResolveActivity.name = ResolverActivity.class.getName(); 9734 mResolveActivity.packageName = mAndroidApplication.packageName; 9735 mResolveActivity.processName = "system:ui"; 9736 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9737 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 9738 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 9739 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 9740 mResolveActivity.exported = true; 9741 mResolveActivity.enabled = true; 9742 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 9743 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 9744 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 9745 | ActivityInfo.CONFIG_SCREEN_LAYOUT 9746 | ActivityInfo.CONFIG_ORIENTATION 9747 | ActivityInfo.CONFIG_KEYBOARD 9748 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 9749 mResolveInfo.activityInfo = mResolveActivity; 9750 mResolveInfo.priority = 0; 9751 mResolveInfo.preferredOrder = 0; 9752 mResolveInfo.match = 0; 9753 mResolveComponentName = new ComponentName( 9754 mAndroidApplication.packageName, mResolveActivity.name); 9755 } 9756 } 9757 } 9758 } 9759 9760 ArrayList<PackageParser.Package> clientLibPkgs = null; 9761 // writer 9762 synchronized (mPackages) { 9763 boolean hasStaticSharedLibs = false; 9764 9765 // Any app can add new static shared libraries 9766 if (pkg.staticSharedLibName != null) { 9767 // Static shared libs don't allow renaming as they have synthetic package 9768 // names to allow install of multiple versions, so use name from manifest. 9769 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName, 9770 pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC, 9771 pkg.manifestPackageName, pkg.mVersionCode)) { 9772 hasStaticSharedLibs = true; 9773 } else { 9774 Slog.w(TAG, "Package " + pkg.packageName + " library " 9775 + pkg.staticSharedLibName + " already exists; skipping"); 9776 } 9777 // Static shared libs cannot be updated once installed since they 9778 // use synthetic package name which includes the version code, so 9779 // not need to update other packages's shared lib dependencies. 9780 } 9781 9782 if (!hasStaticSharedLibs 9783 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9784 // Only system apps can add new dynamic shared libraries. 9785 if (pkg.libraryNames != null) { 9786 for (int i = 0; i < pkg.libraryNames.size(); i++) { 9787 String name = pkg.libraryNames.get(i); 9788 boolean allowed = false; 9789 if (pkg.isUpdatedSystemApp()) { 9790 // New library entries can only be added through the 9791 // system image. This is important to get rid of a lot 9792 // of nasty edge cases: for example if we allowed a non- 9793 // system update of the app to add a library, then uninstalling 9794 // the update would make the library go away, and assumptions 9795 // we made such as through app install filtering would now 9796 // have allowed apps on the device which aren't compatible 9797 // with it. Better to just have the restriction here, be 9798 // conservative, and create many fewer cases that can negatively 9799 // impact the user experience. 9800 final PackageSetting sysPs = mSettings 9801 .getDisabledSystemPkgLPr(pkg.packageName); 9802 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 9803 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) { 9804 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 9805 allowed = true; 9806 break; 9807 } 9808 } 9809 } 9810 } else { 9811 allowed = true; 9812 } 9813 if (allowed) { 9814 if (!addSharedLibraryLPw(null, pkg.packageName, name, 9815 SharedLibraryInfo.VERSION_UNDEFINED, 9816 SharedLibraryInfo.TYPE_DYNAMIC, 9817 pkg.packageName, pkg.mVersionCode)) { 9818 Slog.w(TAG, "Package " + pkg.packageName + " library " 9819 + name + " already exists; skipping"); 9820 } 9821 } else { 9822 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 9823 + name + " that is not declared on system image; skipping"); 9824 } 9825 } 9826 9827 if ((scanFlags & SCAN_BOOTING) == 0) { 9828 // If we are not booting, we need to update any applications 9829 // that are clients of our shared library. If we are booting, 9830 // this will all be done once the scan is complete. 9831 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 9832 } 9833 } 9834 } 9835 } 9836 9837 if ((scanFlags & SCAN_BOOTING) != 0) { 9838 // No apps can run during boot scan, so they don't need to be frozen 9839 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 9840 // Caller asked to not kill app, so it's probably not frozen 9841 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 9842 // Caller asked us to ignore frozen check for some reason; they 9843 // probably didn't know the package name 9844 } else { 9845 // We're doing major surgery on this package, so it better be frozen 9846 // right now to keep it from launching 9847 checkPackageFrozen(pkgName); 9848 } 9849 9850 // Also need to kill any apps that are dependent on the library. 9851 if (clientLibPkgs != null) { 9852 for (int i=0; i<clientLibPkgs.size(); i++) { 9853 PackageParser.Package clientPkg = clientLibPkgs.get(i); 9854 killApplication(clientPkg.applicationInfo.packageName, 9855 clientPkg.applicationInfo.uid, "update lib"); 9856 } 9857 } 9858 9859 // writer 9860 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 9861 9862 boolean createIdmapFailed = false; 9863 synchronized (mPackages) { 9864 // We don't expect installation to fail beyond this point 9865 9866 if (pkgSetting.pkg != null) { 9867 // Note that |user| might be null during the initial boot scan. If a codePath 9868 // for an app has changed during a boot scan, it's due to an app update that's 9869 // part of the system partition and marker changes must be applied to all users. 9870 final int userId = ((user != null) ? user : UserHandle.ALL).getIdentifier(); 9871 final int[] userIds = resolveUserIds(userId); 9872 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, userIds); 9873 } 9874 9875 // Add the new setting to mSettings 9876 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 9877 // Add the new setting to mPackages 9878 mPackages.put(pkg.applicationInfo.packageName, pkg); 9879 // Make sure we don't accidentally delete its data. 9880 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 9881 while (iter.hasNext()) { 9882 PackageCleanItem item = iter.next(); 9883 if (pkgName.equals(item.packageName)) { 9884 iter.remove(); 9885 } 9886 } 9887 9888 // Add the package's KeySets to the global KeySetManagerService 9889 KeySetManagerService ksms = mSettings.mKeySetManagerService; 9890 ksms.addScannedPackageLPw(pkg); 9891 9892 int N = pkg.providers.size(); 9893 StringBuilder r = null; 9894 int i; 9895 for (i=0; i<N; i++) { 9896 PackageParser.Provider p = pkg.providers.get(i); 9897 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 9898 p.info.processName); 9899 mProviders.addProvider(p); 9900 p.syncable = p.info.isSyncable; 9901 if (p.info.authority != null) { 9902 String names[] = p.info.authority.split(";"); 9903 p.info.authority = null; 9904 for (int j = 0; j < names.length; j++) { 9905 if (j == 1 && p.syncable) { 9906 // We only want the first authority for a provider to possibly be 9907 // syncable, so if we already added this provider using a different 9908 // authority clear the syncable flag. We copy the provider before 9909 // changing it because the mProviders object contains a reference 9910 // to a provider that we don't want to change. 9911 // Only do this for the second authority since the resulting provider 9912 // object can be the same for all future authorities for this provider. 9913 p = new PackageParser.Provider(p); 9914 p.syncable = false; 9915 } 9916 if (!mProvidersByAuthority.containsKey(names[j])) { 9917 mProvidersByAuthority.put(names[j], p); 9918 if (p.info.authority == null) { 9919 p.info.authority = names[j]; 9920 } else { 9921 p.info.authority = p.info.authority + ";" + names[j]; 9922 } 9923 if (DEBUG_PACKAGE_SCANNING) { 9924 if (chatty) 9925 Log.d(TAG, "Registered content provider: " + names[j] 9926 + ", className = " + p.info.name + ", isSyncable = " 9927 + p.info.isSyncable); 9928 } 9929 } else { 9930 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 9931 Slog.w(TAG, "Skipping provider name " + names[j] + 9932 " (in package " + pkg.applicationInfo.packageName + 9933 "): name already used by " 9934 + ((other != null && other.getComponentName() != null) 9935 ? other.getComponentName().getPackageName() : "?")); 9936 } 9937 } 9938 } 9939 if (chatty) { 9940 if (r == null) { 9941 r = new StringBuilder(256); 9942 } else { 9943 r.append(' '); 9944 } 9945 r.append(p.info.name); 9946 } 9947 } 9948 if (r != null) { 9949 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 9950 } 9951 9952 N = pkg.services.size(); 9953 r = null; 9954 for (i=0; i<N; i++) { 9955 PackageParser.Service s = pkg.services.get(i); 9956 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 9957 s.info.processName); 9958 mServices.addService(s); 9959 if (chatty) { 9960 if (r == null) { 9961 r = new StringBuilder(256); 9962 } else { 9963 r.append(' '); 9964 } 9965 r.append(s.info.name); 9966 } 9967 } 9968 if (r != null) { 9969 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 9970 } 9971 9972 N = pkg.receivers.size(); 9973 r = null; 9974 for (i=0; i<N; i++) { 9975 PackageParser.Activity a = pkg.receivers.get(i); 9976 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 9977 a.info.processName); 9978 mReceivers.addActivity(a, "receiver"); 9979 if (chatty) { 9980 if (r == null) { 9981 r = new StringBuilder(256); 9982 } else { 9983 r.append(' '); 9984 } 9985 r.append(a.info.name); 9986 } 9987 } 9988 if (r != null) { 9989 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 9990 } 9991 9992 N = pkg.activities.size(); 9993 r = null; 9994 for (i=0; i<N; i++) { 9995 PackageParser.Activity a = pkg.activities.get(i); 9996 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 9997 a.info.processName); 9998 mActivities.addActivity(a, "activity"); 9999 if (chatty) { 10000 if (r == null) { 10001 r = new StringBuilder(256); 10002 } else { 10003 r.append(' '); 10004 } 10005 r.append(a.info.name); 10006 } 10007 } 10008 if (r != null) { 10009 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 10010 } 10011 10012 N = pkg.permissionGroups.size(); 10013 r = null; 10014 for (i=0; i<N; i++) { 10015 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 10016 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 10017 final String curPackageName = cur == null ? null : cur.info.packageName; 10018 // Dont allow ephemeral apps to define new permission groups. 10019 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 10020 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 10021 + pg.info.packageName 10022 + " ignored: instant apps cannot define new permission groups."); 10023 continue; 10024 } 10025 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 10026 if (cur == null || isPackageUpdate) { 10027 mPermissionGroups.put(pg.info.name, pg); 10028 if (chatty) { 10029 if (r == null) { 10030 r = new StringBuilder(256); 10031 } else { 10032 r.append(' '); 10033 } 10034 if (isPackageUpdate) { 10035 r.append("UPD:"); 10036 } 10037 r.append(pg.info.name); 10038 } 10039 } else { 10040 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 10041 + pg.info.packageName + " ignored: original from " 10042 + cur.info.packageName); 10043 if (chatty) { 10044 if (r == null) { 10045 r = new StringBuilder(256); 10046 } else { 10047 r.append(' '); 10048 } 10049 r.append("DUP:"); 10050 r.append(pg.info.name); 10051 } 10052 } 10053 } 10054 if (r != null) { 10055 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 10056 } 10057 10058 N = pkg.permissions.size(); 10059 r = null; 10060 for (i=0; i<N; i++) { 10061 PackageParser.Permission p = pkg.permissions.get(i); 10062 10063 // Dont allow ephemeral apps to define new permissions. 10064 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 10065 Slog.w(TAG, "Permission " + p.info.name + " from package " 10066 + p.info.packageName 10067 + " ignored: instant apps cannot define new permissions."); 10068 continue; 10069 } 10070 10071 // Assume by default that we did not install this permission into the system. 10072 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 10073 10074 // Now that permission groups have a special meaning, we ignore permission 10075 // groups for legacy apps to prevent unexpected behavior. In particular, 10076 // permissions for one app being granted to someone just becase they happen 10077 // to be in a group defined by another app (before this had no implications). 10078 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 10079 p.group = mPermissionGroups.get(p.info.group); 10080 // Warn for a permission in an unknown group. 10081 if (p.info.group != null && p.group == null) { 10082 Slog.w(TAG, "Permission " + p.info.name + " from package " 10083 + p.info.packageName + " in an unknown group " + p.info.group); 10084 } 10085 } 10086 10087 ArrayMap<String, BasePermission> permissionMap = 10088 p.tree ? mSettings.mPermissionTrees 10089 : mSettings.mPermissions; 10090 BasePermission bp = permissionMap.get(p.info.name); 10091 10092 // Allow system apps to redefine non-system permissions 10093 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 10094 final boolean currentOwnerIsSystem = (bp.perm != null 10095 && isSystemApp(bp.perm.owner)); 10096 if (isSystemApp(p.owner)) { 10097 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 10098 // It's a built-in permission and no owner, take ownership now 10099 bp.packageSetting = pkgSetting; 10100 bp.perm = p; 10101 bp.uid = pkg.applicationInfo.uid; 10102 bp.sourcePackage = p.info.packageName; 10103 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 10104 } else if (!currentOwnerIsSystem) { 10105 String msg = "New decl " + p.owner + " of permission " 10106 + p.info.name + " is system; overriding " + bp.sourcePackage; 10107 reportSettingsProblem(Log.WARN, msg); 10108 bp = null; 10109 } 10110 } 10111 } 10112 10113 if (bp == null) { 10114 bp = new BasePermission(p.info.name, p.info.packageName, 10115 BasePermission.TYPE_NORMAL); 10116 permissionMap.put(p.info.name, bp); 10117 } 10118 10119 if (bp.perm == null) { 10120 if (bp.sourcePackage == null 10121 || bp.sourcePackage.equals(p.info.packageName)) { 10122 BasePermission tree = findPermissionTreeLP(p.info.name); 10123 if (tree == null 10124 || tree.sourcePackage.equals(p.info.packageName)) { 10125 bp.packageSetting = pkgSetting; 10126 bp.perm = p; 10127 bp.uid = pkg.applicationInfo.uid; 10128 bp.sourcePackage = p.info.packageName; 10129 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 10130 if (chatty) { 10131 if (r == null) { 10132 r = new StringBuilder(256); 10133 } else { 10134 r.append(' '); 10135 } 10136 r.append(p.info.name); 10137 } 10138 } else { 10139 Slog.w(TAG, "Permission " + p.info.name + " from package " 10140 + p.info.packageName + " ignored: base tree " 10141 + tree.name + " is from package " 10142 + tree.sourcePackage); 10143 } 10144 } else { 10145 Slog.w(TAG, "Permission " + p.info.name + " from package " 10146 + p.info.packageName + " ignored: original from " 10147 + bp.sourcePackage); 10148 } 10149 } else if (chatty) { 10150 if (r == null) { 10151 r = new StringBuilder(256); 10152 } else { 10153 r.append(' '); 10154 } 10155 r.append("DUP:"); 10156 r.append(p.info.name); 10157 } 10158 if (bp.perm == p) { 10159 bp.protectionLevel = p.info.protectionLevel; 10160 } 10161 } 10162 10163 if (r != null) { 10164 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 10165 } 10166 10167 N = pkg.instrumentation.size(); 10168 r = null; 10169 for (i=0; i<N; i++) { 10170 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 10171 a.info.packageName = pkg.applicationInfo.packageName; 10172 a.info.sourceDir = pkg.applicationInfo.sourceDir; 10173 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 10174 a.info.splitNames = pkg.splitNames; 10175 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 10176 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 10177 a.info.splitDependencies = pkg.applicationInfo.splitDependencies; 10178 a.info.dataDir = pkg.applicationInfo.dataDir; 10179 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 10180 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 10181 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 10182 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 10183 mInstrumentation.put(a.getComponentName(), a); 10184 if (chatty) { 10185 if (r == null) { 10186 r = new StringBuilder(256); 10187 } else { 10188 r.append(' '); 10189 } 10190 r.append(a.info.name); 10191 } 10192 } 10193 if (r != null) { 10194 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 10195 } 10196 10197 if (pkg.protectedBroadcasts != null) { 10198 N = pkg.protectedBroadcasts.size(); 10199 for (i=0; i<N; i++) { 10200 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 10201 } 10202 } 10203 10204 // Create idmap files for pairs of (packages, overlay packages). 10205 // Note: "android", ie framework-res.apk, is handled by native layers. 10206 if (pkg.mOverlayTarget != null) { 10207 // This is an overlay package. 10208 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 10209 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 10210 mOverlays.put(pkg.mOverlayTarget, 10211 new ArrayMap<String, PackageParser.Package>()); 10212 } 10213 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 10214 map.put(pkg.packageName, pkg); 10215 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 10216 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 10217 createIdmapFailed = true; 10218 } 10219 } 10220 } else if (mOverlays.containsKey(pkg.packageName) && 10221 !pkg.packageName.equals("android")) { 10222 // This is a regular package, with one or more known overlay packages. 10223 createIdmapsForPackageLI(pkg); 10224 } 10225 } 10226 10227 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10228 10229 if (createIdmapFailed) { 10230 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10231 "scanPackageLI failed to createIdmap"); 10232 } 10233 } 10234 10235 private static void maybeRenameForeignDexMarkers(PackageParser.Package existing, 10236 PackageParser.Package update, int[] userIds) { 10237 if (existing.applicationInfo == null || update.applicationInfo == null) { 10238 // This isn't due to an app installation. 10239 return; 10240 } 10241 10242 final File oldCodePath = new File(existing.applicationInfo.getCodePath()); 10243 final File newCodePath = new File(update.applicationInfo.getCodePath()); 10244 10245 // The codePath hasn't changed, so there's nothing for us to do. 10246 if (Objects.equals(oldCodePath, newCodePath)) { 10247 return; 10248 } 10249 10250 File canonicalNewCodePath; 10251 try { 10252 canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath)); 10253 } catch (IOException e) { 10254 Slog.w(TAG, "Failed to get canonical path.", e); 10255 return; 10256 } 10257 10258 // This is a bit of a hack. The oldCodePath doesn't exist at this point (because 10259 // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume 10260 // that the last component of the path (i.e, the name) doesn't need canonicalization 10261 // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now 10262 // but may change in the future. Hopefully this function won't exist at that point. 10263 final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(), 10264 oldCodePath.getName()); 10265 10266 // Calculate the prefixes of the markers. These are just the paths with "/" replaced 10267 // with "@". 10268 String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@'); 10269 if (!oldMarkerPrefix.endsWith("@")) { 10270 oldMarkerPrefix += "@"; 10271 } 10272 String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@'); 10273 if (!newMarkerPrefix.endsWith("@")) { 10274 newMarkerPrefix += "@"; 10275 } 10276 10277 List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly(); 10278 List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size()); 10279 for (String updatedPath : updatedPaths) { 10280 String updatedPathName = new File(updatedPath).getName(); 10281 markerSuffixes.add(updatedPathName.replace('/', '@')); 10282 } 10283 10284 for (int userId : userIds) { 10285 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId); 10286 10287 for (String markerSuffix : markerSuffixes) { 10288 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix); 10289 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix); 10290 if (oldForeignUseMark.exists()) { 10291 try { 10292 Os.rename(oldForeignUseMark.getAbsolutePath(), 10293 newForeignUseMark.getAbsolutePath()); 10294 } catch (ErrnoException e) { 10295 Slog.w(TAG, "Failed to rename foreign use marker", e); 10296 oldForeignUseMark.delete(); 10297 } 10298 } 10299 } 10300 } 10301 } 10302 10303 /** 10304 * Derive the ABI of a non-system package located at {@code scanFile}. This information 10305 * is derived purely on the basis of the contents of {@code scanFile} and 10306 * {@code cpuAbiOverride}. 10307 * 10308 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 10309 */ 10310 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile, 10311 String cpuAbiOverride, boolean extractLibs, 10312 File appLib32InstallDir) 10313 throws PackageManagerException { 10314 // Give ourselves some initial paths; we'll come back for another 10315 // pass once we've determined ABI below. 10316 setNativeLibraryPaths(pkg, appLib32InstallDir); 10317 10318 // We would never need to extract libs for forward-locked and external packages, 10319 // since the container service will do it for us. We shouldn't attempt to 10320 // extract libs from system app when it was not updated. 10321 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 10322 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 10323 extractLibs = false; 10324 } 10325 10326 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 10327 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 10328 10329 NativeLibraryHelper.Handle handle = null; 10330 try { 10331 handle = NativeLibraryHelper.Handle.create(pkg); 10332 // TODO(multiArch): This can be null for apps that didn't go through the 10333 // usual installation process. We can calculate it again, like we 10334 // do during install time. 10335 // 10336 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 10337 // unnecessary. 10338 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 10339 10340 // Null out the abis so that they can be recalculated. 10341 pkg.applicationInfo.primaryCpuAbi = null; 10342 pkg.applicationInfo.secondaryCpuAbi = null; 10343 if (isMultiArch(pkg.applicationInfo)) { 10344 // Warn if we've set an abiOverride for multi-lib packages.. 10345 // By definition, we need to copy both 32 and 64 bit libraries for 10346 // such packages. 10347 if (pkg.cpuAbiOverride != null 10348 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 10349 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 10350 } 10351 10352 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 10353 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 10354 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 10355 if (extractLibs) { 10356 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10357 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10358 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 10359 useIsaSpecificSubdirs); 10360 } else { 10361 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10362 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 10363 } 10364 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10365 } 10366 10367 maybeThrowExceptionForMultiArchCopy( 10368 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 10369 10370 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 10371 if (extractLibs) { 10372 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10373 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10374 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 10375 useIsaSpecificSubdirs); 10376 } else { 10377 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10378 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 10379 } 10380 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10381 } 10382 10383 maybeThrowExceptionForMultiArchCopy( 10384 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 10385 10386 if (abi64 >= 0) { 10387 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 10388 } 10389 10390 if (abi32 >= 0) { 10391 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 10392 if (abi64 >= 0) { 10393 if (pkg.use32bitAbi) { 10394 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 10395 pkg.applicationInfo.primaryCpuAbi = abi; 10396 } else { 10397 pkg.applicationInfo.secondaryCpuAbi = abi; 10398 } 10399 } else { 10400 pkg.applicationInfo.primaryCpuAbi = abi; 10401 } 10402 } 10403 10404 } else { 10405 String[] abiList = (cpuAbiOverride != null) ? 10406 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 10407 10408 // Enable gross and lame hacks for apps that are built with old 10409 // SDK tools. We must scan their APKs for renderscript bitcode and 10410 // not launch them if it's present. Don't bother checking on devices 10411 // that don't have 64 bit support. 10412 boolean needsRenderScriptOverride = false; 10413 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 10414 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 10415 abiList = Build.SUPPORTED_32_BIT_ABIS; 10416 needsRenderScriptOverride = true; 10417 } 10418 10419 final int copyRet; 10420 if (extractLibs) { 10421 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10422 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10423 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 10424 } else { 10425 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10426 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 10427 } 10428 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10429 10430 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 10431 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 10432 "Error unpackaging native libs for app, errorCode=" + copyRet); 10433 } 10434 10435 if (copyRet >= 0) { 10436 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 10437 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 10438 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 10439 } else if (needsRenderScriptOverride) { 10440 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 10441 } 10442 } 10443 } catch (IOException ioe) { 10444 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 10445 } finally { 10446 IoUtils.closeQuietly(handle); 10447 } 10448 10449 // Now that we've calculated the ABIs and determined if it's an internal app, 10450 // we will go ahead and populate the nativeLibraryPath. 10451 setNativeLibraryPaths(pkg, appLib32InstallDir); 10452 } 10453 10454 /** 10455 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 10456 * i.e, so that all packages can be run inside a single process if required. 10457 * 10458 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 10459 * this function will either try and make the ABI for all packages in {@code packagesForUser} 10460 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 10461 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 10462 * updating a package that belongs to a shared user. 10463 * 10464 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 10465 * adds unnecessary complexity. 10466 */ 10467 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 10468 PackageParser.Package scannedPackage) { 10469 String requiredInstructionSet = null; 10470 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 10471 requiredInstructionSet = VMRuntime.getInstructionSet( 10472 scannedPackage.applicationInfo.primaryCpuAbi); 10473 } 10474 10475 PackageSetting requirer = null; 10476 for (PackageSetting ps : packagesForUser) { 10477 // If packagesForUser contains scannedPackage, we skip it. This will happen 10478 // when scannedPackage is an update of an existing package. Without this check, 10479 // we will never be able to change the ABI of any package belonging to a shared 10480 // user, even if it's compatible with other packages. 10481 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 10482 if (ps.primaryCpuAbiString == null) { 10483 continue; 10484 } 10485 10486 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 10487 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 10488 // We have a mismatch between instruction sets (say arm vs arm64) warn about 10489 // this but there's not much we can do. 10490 String errorMessage = "Instruction set mismatch, " 10491 + ((requirer == null) ? "[caller]" : requirer) 10492 + " requires " + requiredInstructionSet + " whereas " + ps 10493 + " requires " + instructionSet; 10494 Slog.w(TAG, errorMessage); 10495 } 10496 10497 if (requiredInstructionSet == null) { 10498 requiredInstructionSet = instructionSet; 10499 requirer = ps; 10500 } 10501 } 10502 } 10503 10504 if (requiredInstructionSet != null) { 10505 String adjustedAbi; 10506 if (requirer != null) { 10507 // requirer != null implies that either scannedPackage was null or that scannedPackage 10508 // did not require an ABI, in which case we have to adjust scannedPackage to match 10509 // the ABI of the set (which is the same as requirer's ABI) 10510 adjustedAbi = requirer.primaryCpuAbiString; 10511 if (scannedPackage != null) { 10512 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 10513 } 10514 } else { 10515 // requirer == null implies that we're updating all ABIs in the set to 10516 // match scannedPackage. 10517 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 10518 } 10519 10520 for (PackageSetting ps : packagesForUser) { 10521 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 10522 if (ps.primaryCpuAbiString != null) { 10523 continue; 10524 } 10525 10526 ps.primaryCpuAbiString = adjustedAbi; 10527 if (ps.pkg != null && ps.pkg.applicationInfo != null && 10528 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 10529 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 10530 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 10531 + " (requirer=" 10532 + (requirer == null ? "null" : requirer.pkg.packageName) 10533 + ", scannedPackage=" 10534 + (scannedPackage != null ? scannedPackage.packageName : "null") 10535 + ")"); 10536 try { 10537 mInstaller.rmdex(ps.codePathString, 10538 getDexCodeInstructionSet(getPreferredInstructionSet())); 10539 } catch (InstallerException ignored) { 10540 } 10541 } 10542 } 10543 } 10544 } 10545 } 10546 10547 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 10548 synchronized (mPackages) { 10549 mResolverReplaced = true; 10550 // Set up information for custom user intent resolution activity. 10551 mResolveActivity.applicationInfo = pkg.applicationInfo; 10552 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 10553 mResolveActivity.packageName = pkg.applicationInfo.packageName; 10554 mResolveActivity.processName = pkg.applicationInfo.packageName; 10555 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 10556 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 10557 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 10558 mResolveActivity.theme = 0; 10559 mResolveActivity.exported = true; 10560 mResolveActivity.enabled = true; 10561 mResolveInfo.activityInfo = mResolveActivity; 10562 mResolveInfo.priority = 0; 10563 mResolveInfo.preferredOrder = 0; 10564 mResolveInfo.match = 0; 10565 mResolveComponentName = mCustomResolverComponentName; 10566 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 10567 mResolveComponentName); 10568 } 10569 } 10570 10571 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 10572 if (installerComponent == null) { 10573 if (DEBUG_EPHEMERAL) { 10574 Slog.d(TAG, "Clear ephemeral installer activity"); 10575 } 10576 mEphemeralInstallerActivity.applicationInfo = null; 10577 return; 10578 } 10579 10580 if (DEBUG_EPHEMERAL) { 10581 Slog.d(TAG, "Set ephemeral installer activity: " + installerComponent); 10582 } 10583 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 10584 // Set up information for ephemeral installer activity 10585 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 10586 mEphemeralInstallerActivity.name = installerComponent.getClassName(); 10587 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 10588 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 10589 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 10590 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 10591 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 10592 mEphemeralInstallerActivity.theme = 0; 10593 mEphemeralInstallerActivity.exported = true; 10594 mEphemeralInstallerActivity.enabled = true; 10595 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 10596 mEphemeralInstallerInfo.priority = 0; 10597 mEphemeralInstallerInfo.preferredOrder = 1; 10598 mEphemeralInstallerInfo.isDefault = true; 10599 mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 10600 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 10601 } 10602 10603 private static String calculateBundledApkRoot(final String codePathString) { 10604 final File codePath = new File(codePathString); 10605 final File codeRoot; 10606 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 10607 codeRoot = Environment.getRootDirectory(); 10608 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 10609 codeRoot = Environment.getOemDirectory(); 10610 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 10611 codeRoot = Environment.getVendorDirectory(); 10612 } else { 10613 // Unrecognized code path; take its top real segment as the apk root: 10614 // e.g. /something/app/blah.apk => /something 10615 try { 10616 File f = codePath.getCanonicalFile(); 10617 File parent = f.getParentFile(); // non-null because codePath is a file 10618 File tmp; 10619 while ((tmp = parent.getParentFile()) != null) { 10620 f = parent; 10621 parent = tmp; 10622 } 10623 codeRoot = f; 10624 Slog.w(TAG, "Unrecognized code path " 10625 + codePath + " - using " + codeRoot); 10626 } catch (IOException e) { 10627 // Can't canonicalize the code path -- shenanigans? 10628 Slog.w(TAG, "Can't canonicalize code path " + codePath); 10629 return Environment.getRootDirectory().getPath(); 10630 } 10631 } 10632 return codeRoot.getPath(); 10633 } 10634 10635 /** 10636 * Derive and set the location of native libraries for the given package, 10637 * which varies depending on where and how the package was installed. 10638 */ 10639 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) { 10640 final ApplicationInfo info = pkg.applicationInfo; 10641 final String codePath = pkg.codePath; 10642 final File codeFile = new File(codePath); 10643 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 10644 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 10645 10646 info.nativeLibraryRootDir = null; 10647 info.nativeLibraryRootRequiresIsa = false; 10648 info.nativeLibraryDir = null; 10649 info.secondaryNativeLibraryDir = null; 10650 10651 if (isApkFile(codeFile)) { 10652 // Monolithic install 10653 if (bundledApp) { 10654 // If "/system/lib64/apkname" exists, assume that is the per-package 10655 // native library directory to use; otherwise use "/system/lib/apkname". 10656 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 10657 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 10658 getPrimaryInstructionSet(info)); 10659 10660 // This is a bundled system app so choose the path based on the ABI. 10661 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 10662 // is just the default path. 10663 final String apkName = deriveCodePathName(codePath); 10664 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 10665 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 10666 apkName).getAbsolutePath(); 10667 10668 if (info.secondaryCpuAbi != null) { 10669 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 10670 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 10671 secondaryLibDir, apkName).getAbsolutePath(); 10672 } 10673 } else if (asecApp) { 10674 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 10675 .getAbsolutePath(); 10676 } else { 10677 final String apkName = deriveCodePathName(codePath); 10678 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName) 10679 .getAbsolutePath(); 10680 } 10681 10682 info.nativeLibraryRootRequiresIsa = false; 10683 info.nativeLibraryDir = info.nativeLibraryRootDir; 10684 } else { 10685 // Cluster install 10686 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 10687 info.nativeLibraryRootRequiresIsa = true; 10688 10689 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 10690 getPrimaryInstructionSet(info)).getAbsolutePath(); 10691 10692 if (info.secondaryCpuAbi != null) { 10693 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 10694 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 10695 } 10696 } 10697 } 10698 10699 /** 10700 * Calculate the abis and roots for a bundled app. These can uniquely 10701 * be determined from the contents of the system partition, i.e whether 10702 * it contains 64 or 32 bit shared libraries etc. We do not validate any 10703 * of this information, and instead assume that the system was built 10704 * sensibly. 10705 */ 10706 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg, 10707 PackageSetting pkgSetting) { 10708 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 10709 10710 // If "/system/lib64/apkname" exists, assume that is the per-package 10711 // native library directory to use; otherwise use "/system/lib/apkname". 10712 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 10713 setBundledAppAbi(pkg, apkRoot, apkName); 10714 // pkgSetting might be null during rescan following uninstall of updates 10715 // to a bundled app, so accommodate that possibility. The settings in 10716 // that case will be established later from the parsed package. 10717 // 10718 // If the settings aren't null, sync them up with what we've just derived. 10719 // note that apkRoot isn't stored in the package settings. 10720 if (pkgSetting != null) { 10721 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 10722 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 10723 } 10724 } 10725 10726 /** 10727 * Deduces the ABI of a bundled app and sets the relevant fields on the 10728 * parsed pkg object. 10729 * 10730 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 10731 * under which system libraries are installed. 10732 * @param apkName the name of the installed package. 10733 */ 10734 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 10735 final File codeFile = new File(pkg.codePath); 10736 10737 final boolean has64BitLibs; 10738 final boolean has32BitLibs; 10739 if (isApkFile(codeFile)) { 10740 // Monolithic install 10741 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 10742 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 10743 } else { 10744 // Cluster install 10745 final File rootDir = new File(codeFile, LIB_DIR_NAME); 10746 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 10747 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 10748 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 10749 has64BitLibs = (new File(rootDir, isa)).exists(); 10750 } else { 10751 has64BitLibs = false; 10752 } 10753 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 10754 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 10755 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 10756 has32BitLibs = (new File(rootDir, isa)).exists(); 10757 } else { 10758 has32BitLibs = false; 10759 } 10760 } 10761 10762 if (has64BitLibs && !has32BitLibs) { 10763 // The package has 64 bit libs, but not 32 bit libs. Its primary 10764 // ABI should be 64 bit. We can safely assume here that the bundled 10765 // native libraries correspond to the most preferred ABI in the list. 10766 10767 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10768 pkg.applicationInfo.secondaryCpuAbi = null; 10769 } else if (has32BitLibs && !has64BitLibs) { 10770 // The package has 32 bit libs but not 64 bit libs. Its primary 10771 // ABI should be 32 bit. 10772 10773 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10774 pkg.applicationInfo.secondaryCpuAbi = null; 10775 } else if (has32BitLibs && has64BitLibs) { 10776 // The application has both 64 and 32 bit bundled libraries. We check 10777 // here that the app declares multiArch support, and warn if it doesn't. 10778 // 10779 // We will be lenient here and record both ABIs. The primary will be the 10780 // ABI that's higher on the list, i.e, a device that's configured to prefer 10781 // 64 bit apps will see a 64 bit primary ABI, 10782 10783 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 10784 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 10785 } 10786 10787 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 10788 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10789 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10790 } else { 10791 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10792 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10793 } 10794 } else { 10795 pkg.applicationInfo.primaryCpuAbi = null; 10796 pkg.applicationInfo.secondaryCpuAbi = null; 10797 } 10798 } 10799 10800 private void killApplication(String pkgName, int appId, String reason) { 10801 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 10802 } 10803 10804 private void killApplication(String pkgName, int appId, int userId, String reason) { 10805 // Request the ActivityManager to kill the process(only for existing packages) 10806 // so that we do not end up in a confused state while the user is still using the older 10807 // version of the application while the new one gets installed. 10808 final long token = Binder.clearCallingIdentity(); 10809 try { 10810 IActivityManager am = ActivityManager.getService(); 10811 if (am != null) { 10812 try { 10813 am.killApplication(pkgName, appId, userId, reason); 10814 } catch (RemoteException e) { 10815 } 10816 } 10817 } finally { 10818 Binder.restoreCallingIdentity(token); 10819 } 10820 } 10821 10822 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 10823 // Remove the parent package setting 10824 PackageSetting ps = (PackageSetting) pkg.mExtras; 10825 if (ps != null) { 10826 removePackageLI(ps, chatty); 10827 } 10828 // Remove the child package setting 10829 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10830 for (int i = 0; i < childCount; i++) { 10831 PackageParser.Package childPkg = pkg.childPackages.get(i); 10832 ps = (PackageSetting) childPkg.mExtras; 10833 if (ps != null) { 10834 removePackageLI(ps, chatty); 10835 } 10836 } 10837 } 10838 10839 void removePackageLI(PackageSetting ps, boolean chatty) { 10840 if (DEBUG_INSTALL) { 10841 if (chatty) 10842 Log.d(TAG, "Removing package " + ps.name); 10843 } 10844 10845 // writer 10846 synchronized (mPackages) { 10847 mPackages.remove(ps.name); 10848 final PackageParser.Package pkg = ps.pkg; 10849 if (pkg != null) { 10850 cleanPackageDataStructuresLILPw(pkg, chatty); 10851 } 10852 } 10853 } 10854 10855 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 10856 if (DEBUG_INSTALL) { 10857 if (chatty) 10858 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 10859 } 10860 10861 // writer 10862 synchronized (mPackages) { 10863 // Remove the parent package 10864 mPackages.remove(pkg.applicationInfo.packageName); 10865 cleanPackageDataStructuresLILPw(pkg, chatty); 10866 10867 // Remove the child packages 10868 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10869 for (int i = 0; i < childCount; i++) { 10870 PackageParser.Package childPkg = pkg.childPackages.get(i); 10871 mPackages.remove(childPkg.applicationInfo.packageName); 10872 cleanPackageDataStructuresLILPw(childPkg, chatty); 10873 } 10874 } 10875 } 10876 10877 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 10878 int N = pkg.providers.size(); 10879 StringBuilder r = null; 10880 int i; 10881 for (i=0; i<N; i++) { 10882 PackageParser.Provider p = pkg.providers.get(i); 10883 mProviders.removeProvider(p); 10884 if (p.info.authority == null) { 10885 10886 /* There was another ContentProvider with this authority when 10887 * this app was installed so this authority is null, 10888 * Ignore it as we don't have to unregister the provider. 10889 */ 10890 continue; 10891 } 10892 String names[] = p.info.authority.split(";"); 10893 for (int j = 0; j < names.length; j++) { 10894 if (mProvidersByAuthority.get(names[j]) == p) { 10895 mProvidersByAuthority.remove(names[j]); 10896 if (DEBUG_REMOVE) { 10897 if (chatty) 10898 Log.d(TAG, "Unregistered content provider: " + names[j] 10899 + ", className = " + p.info.name + ", isSyncable = " 10900 + p.info.isSyncable); 10901 } 10902 } 10903 } 10904 if (DEBUG_REMOVE && chatty) { 10905 if (r == null) { 10906 r = new StringBuilder(256); 10907 } else { 10908 r.append(' '); 10909 } 10910 r.append(p.info.name); 10911 } 10912 } 10913 if (r != null) { 10914 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 10915 } 10916 10917 N = pkg.services.size(); 10918 r = null; 10919 for (i=0; i<N; i++) { 10920 PackageParser.Service s = pkg.services.get(i); 10921 mServices.removeService(s); 10922 if (chatty) { 10923 if (r == null) { 10924 r = new StringBuilder(256); 10925 } else { 10926 r.append(' '); 10927 } 10928 r.append(s.info.name); 10929 } 10930 } 10931 if (r != null) { 10932 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 10933 } 10934 10935 N = pkg.receivers.size(); 10936 r = null; 10937 for (i=0; i<N; i++) { 10938 PackageParser.Activity a = pkg.receivers.get(i); 10939 mReceivers.removeActivity(a, "receiver"); 10940 if (DEBUG_REMOVE && chatty) { 10941 if (r == null) { 10942 r = new StringBuilder(256); 10943 } else { 10944 r.append(' '); 10945 } 10946 r.append(a.info.name); 10947 } 10948 } 10949 if (r != null) { 10950 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 10951 } 10952 10953 N = pkg.activities.size(); 10954 r = null; 10955 for (i=0; i<N; i++) { 10956 PackageParser.Activity a = pkg.activities.get(i); 10957 mActivities.removeActivity(a, "activity"); 10958 if (DEBUG_REMOVE && chatty) { 10959 if (r == null) { 10960 r = new StringBuilder(256); 10961 } else { 10962 r.append(' '); 10963 } 10964 r.append(a.info.name); 10965 } 10966 } 10967 if (r != null) { 10968 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 10969 } 10970 10971 N = pkg.permissions.size(); 10972 r = null; 10973 for (i=0; i<N; i++) { 10974 PackageParser.Permission p = pkg.permissions.get(i); 10975 BasePermission bp = mSettings.mPermissions.get(p.info.name); 10976 if (bp == null) { 10977 bp = mSettings.mPermissionTrees.get(p.info.name); 10978 } 10979 if (bp != null && bp.perm == p) { 10980 bp.perm = null; 10981 if (DEBUG_REMOVE && chatty) { 10982 if (r == null) { 10983 r = new StringBuilder(256); 10984 } else { 10985 r.append(' '); 10986 } 10987 r.append(p.info.name); 10988 } 10989 } 10990 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 10991 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 10992 if (appOpPkgs != null) { 10993 appOpPkgs.remove(pkg.packageName); 10994 } 10995 } 10996 } 10997 if (r != null) { 10998 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 10999 } 11000 11001 N = pkg.requestedPermissions.size(); 11002 r = null; 11003 for (i=0; i<N; i++) { 11004 String perm = pkg.requestedPermissions.get(i); 11005 BasePermission bp = mSettings.mPermissions.get(perm); 11006 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11007 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 11008 if (appOpPkgs != null) { 11009 appOpPkgs.remove(pkg.packageName); 11010 if (appOpPkgs.isEmpty()) { 11011 mAppOpPermissionPackages.remove(perm); 11012 } 11013 } 11014 } 11015 } 11016 if (r != null) { 11017 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 11018 } 11019 11020 N = pkg.instrumentation.size(); 11021 r = null; 11022 for (i=0; i<N; i++) { 11023 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 11024 mInstrumentation.remove(a.getComponentName()); 11025 if (DEBUG_REMOVE && chatty) { 11026 if (r == null) { 11027 r = new StringBuilder(256); 11028 } else { 11029 r.append(' '); 11030 } 11031 r.append(a.info.name); 11032 } 11033 } 11034 if (r != null) { 11035 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 11036 } 11037 11038 r = null; 11039 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11040 // Only system apps can hold shared libraries. 11041 if (pkg.libraryNames != null) { 11042 for (i = 0; i < pkg.libraryNames.size(); i++) { 11043 String name = pkg.libraryNames.get(i); 11044 if (removeSharedLibraryLPw(name, 0)) { 11045 if (DEBUG_REMOVE && chatty) { 11046 if (r == null) { 11047 r = new StringBuilder(256); 11048 } else { 11049 r.append(' '); 11050 } 11051 r.append(name); 11052 } 11053 } 11054 } 11055 } 11056 } 11057 11058 r = null; 11059 11060 // Any package can hold static shared libraries. 11061 if (pkg.staticSharedLibName != null) { 11062 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) { 11063 if (DEBUG_REMOVE && chatty) { 11064 if (r == null) { 11065 r = new StringBuilder(256); 11066 } else { 11067 r.append(' '); 11068 } 11069 r.append(pkg.staticSharedLibName); 11070 } 11071 } 11072 } 11073 11074 if (r != null) { 11075 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 11076 } 11077 } 11078 11079 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 11080 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 11081 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 11082 return true; 11083 } 11084 } 11085 return false; 11086 } 11087 11088 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 11089 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 11090 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 11091 11092 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 11093 // Update the parent permissions 11094 updatePermissionsLPw(pkg.packageName, pkg, flags); 11095 // Update the child permissions 11096 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 11097 for (int i = 0; i < childCount; i++) { 11098 PackageParser.Package childPkg = pkg.childPackages.get(i); 11099 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 11100 } 11101 } 11102 11103 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 11104 int flags) { 11105 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 11106 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 11107 } 11108 11109 private void updatePermissionsLPw(String changingPkg, 11110 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 11111 // Make sure there are no dangling permission trees. 11112 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 11113 while (it.hasNext()) { 11114 final BasePermission bp = it.next(); 11115 if (bp.packageSetting == null) { 11116 // We may not yet have parsed the package, so just see if 11117 // we still know about its settings. 11118 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 11119 } 11120 if (bp.packageSetting == null) { 11121 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 11122 + " from package " + bp.sourcePackage); 11123 it.remove(); 11124 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 11125 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 11126 Slog.i(TAG, "Removing old permission tree: " + bp.name 11127 + " from package " + bp.sourcePackage); 11128 flags |= UPDATE_PERMISSIONS_ALL; 11129 it.remove(); 11130 } 11131 } 11132 } 11133 11134 // Make sure all dynamic permissions have been assigned to a package, 11135 // and make sure there are no dangling permissions. 11136 it = mSettings.mPermissions.values().iterator(); 11137 while (it.hasNext()) { 11138 final BasePermission bp = it.next(); 11139 if (bp.type == BasePermission.TYPE_DYNAMIC) { 11140 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 11141 + bp.name + " pkg=" + bp.sourcePackage 11142 + " info=" + bp.pendingInfo); 11143 if (bp.packageSetting == null && bp.pendingInfo != null) { 11144 final BasePermission tree = findPermissionTreeLP(bp.name); 11145 if (tree != null && tree.perm != null) { 11146 bp.packageSetting = tree.packageSetting; 11147 bp.perm = new PackageParser.Permission(tree.perm.owner, 11148 new PermissionInfo(bp.pendingInfo)); 11149 bp.perm.info.packageName = tree.perm.info.packageName; 11150 bp.perm.info.name = bp.name; 11151 bp.uid = tree.uid; 11152 } 11153 } 11154 } 11155 if (bp.packageSetting == null) { 11156 // We may not yet have parsed the package, so just see if 11157 // we still know about its settings. 11158 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 11159 } 11160 if (bp.packageSetting == null) { 11161 Slog.w(TAG, "Removing dangling permission: " + bp.name 11162 + " from package " + bp.sourcePackage); 11163 it.remove(); 11164 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 11165 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 11166 Slog.i(TAG, "Removing old permission: " + bp.name 11167 + " from package " + bp.sourcePackage); 11168 flags |= UPDATE_PERMISSIONS_ALL; 11169 it.remove(); 11170 } 11171 } 11172 } 11173 11174 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 11175 // Now update the permissions for all packages, in particular 11176 // replace the granted permissions of the system packages. 11177 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 11178 for (PackageParser.Package pkg : mPackages.values()) { 11179 if (pkg != pkgInfo) { 11180 // Only replace for packages on requested volume 11181 final String volumeUuid = getVolumeUuidForPackage(pkg); 11182 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 11183 && Objects.equals(replaceVolumeUuid, volumeUuid); 11184 grantPermissionsLPw(pkg, replace, changingPkg); 11185 } 11186 } 11187 } 11188 11189 if (pkgInfo != null) { 11190 // Only replace for packages on requested volume 11191 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 11192 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 11193 && Objects.equals(replaceVolumeUuid, volumeUuid); 11194 grantPermissionsLPw(pkgInfo, replace, changingPkg); 11195 } 11196 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 11197 } 11198 11199 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 11200 String packageOfInterest) { 11201 // IMPORTANT: There are two types of permissions: install and runtime. 11202 // Install time permissions are granted when the app is installed to 11203 // all device users and users added in the future. Runtime permissions 11204 // are granted at runtime explicitly to specific users. Normal and signature 11205 // protected permissions are install time permissions. Dangerous permissions 11206 // are install permissions if the app's target SDK is Lollipop MR1 or older, 11207 // otherwise they are runtime permissions. This function does not manage 11208 // runtime permissions except for the case an app targeting Lollipop MR1 11209 // being upgraded to target a newer SDK, in which case dangerous permissions 11210 // are transformed from install time to runtime ones. 11211 11212 final PackageSetting ps = (PackageSetting) pkg.mExtras; 11213 if (ps == null) { 11214 return; 11215 } 11216 11217 PermissionsState permissionsState = ps.getPermissionsState(); 11218 PermissionsState origPermissions = permissionsState; 11219 11220 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 11221 11222 boolean runtimePermissionsRevoked = false; 11223 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 11224 11225 boolean changedInstallPermission = false; 11226 11227 if (replace) { 11228 ps.installPermissionsFixed = false; 11229 if (!ps.isSharedUser()) { 11230 origPermissions = new PermissionsState(permissionsState); 11231 permissionsState.reset(); 11232 } else { 11233 // We need to know only about runtime permission changes since the 11234 // calling code always writes the install permissions state but 11235 // the runtime ones are written only if changed. The only cases of 11236 // changed runtime permissions here are promotion of an install to 11237 // runtime and revocation of a runtime from a shared user. 11238 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 11239 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 11240 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 11241 runtimePermissionsRevoked = true; 11242 } 11243 } 11244 } 11245 11246 permissionsState.setGlobalGids(mGlobalGids); 11247 11248 final int N = pkg.requestedPermissions.size(); 11249 for (int i=0; i<N; i++) { 11250 final String name = pkg.requestedPermissions.get(i); 11251 final BasePermission bp = mSettings.mPermissions.get(name); 11252 11253 if (DEBUG_INSTALL) { 11254 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 11255 } 11256 11257 if (bp == null || bp.packageSetting == null) { 11258 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 11259 Slog.w(TAG, "Unknown permission " + name 11260 + " in package " + pkg.packageName); 11261 } 11262 continue; 11263 } 11264 11265 11266 // Limit ephemeral apps to ephemeral allowed permissions. 11267 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) { 11268 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package " 11269 + pkg.packageName); 11270 continue; 11271 } 11272 11273 final String perm = bp.name; 11274 boolean allowedSig = false; 11275 int grant = GRANT_DENIED; 11276 11277 // Keep track of app op permissions. 11278 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11279 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 11280 if (pkgs == null) { 11281 pkgs = new ArraySet<>(); 11282 mAppOpPermissionPackages.put(bp.name, pkgs); 11283 } 11284 pkgs.add(pkg.packageName); 11285 } 11286 11287 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 11288 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 11289 >= Build.VERSION_CODES.M; 11290 switch (level) { 11291 case PermissionInfo.PROTECTION_NORMAL: { 11292 // For all apps normal permissions are install time ones. 11293 grant = GRANT_INSTALL; 11294 } break; 11295 11296 case PermissionInfo.PROTECTION_DANGEROUS: { 11297 // If a permission review is required for legacy apps we represent 11298 // their permissions as always granted runtime ones since we need 11299 // to keep the review required permission flag per user while an 11300 // install permission's state is shared across all users. 11301 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) { 11302 // For legacy apps dangerous permissions are install time ones. 11303 grant = GRANT_INSTALL; 11304 } else if (origPermissions.hasInstallPermission(bp.name)) { 11305 // For legacy apps that became modern, install becomes runtime. 11306 grant = GRANT_UPGRADE; 11307 } else if (mPromoteSystemApps 11308 && isSystemApp(ps) 11309 && mExistingSystemPackages.contains(ps.name)) { 11310 // For legacy system apps, install becomes runtime. 11311 // We cannot check hasInstallPermission() for system apps since those 11312 // permissions were granted implicitly and not persisted pre-M. 11313 grant = GRANT_UPGRADE; 11314 } else { 11315 // For modern apps keep runtime permissions unchanged. 11316 grant = GRANT_RUNTIME; 11317 } 11318 } break; 11319 11320 case PermissionInfo.PROTECTION_SIGNATURE: { 11321 // For all apps signature permissions are install time ones. 11322 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 11323 if (allowedSig) { 11324 grant = GRANT_INSTALL; 11325 } 11326 } break; 11327 } 11328 11329 if (DEBUG_INSTALL) { 11330 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 11331 } 11332 11333 if (grant != GRANT_DENIED) { 11334 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 11335 // If this is an existing, non-system package, then 11336 // we can't add any new permissions to it. 11337 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 11338 // Except... if this is a permission that was added 11339 // to the platform (note: need to only do this when 11340 // updating the platform). 11341 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 11342 grant = GRANT_DENIED; 11343 } 11344 } 11345 } 11346 11347 switch (grant) { 11348 case GRANT_INSTALL: { 11349 // Revoke this as runtime permission to handle the case of 11350 // a runtime permission being downgraded to an install one. 11351 // Also in permission review mode we keep dangerous permissions 11352 // for legacy apps 11353 for (int userId : UserManagerService.getInstance().getUserIds()) { 11354 if (origPermissions.getRuntimePermissionState( 11355 bp.name, userId) != null) { 11356 // Revoke the runtime permission and clear the flags. 11357 origPermissions.revokeRuntimePermission(bp, userId); 11358 origPermissions.updatePermissionFlags(bp, userId, 11359 PackageManager.MASK_PERMISSION_FLAGS, 0); 11360 // If we revoked a permission permission, we have to write. 11361 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11362 changedRuntimePermissionUserIds, userId); 11363 } 11364 } 11365 // Grant an install permission. 11366 if (permissionsState.grantInstallPermission(bp) != 11367 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11368 changedInstallPermission = true; 11369 } 11370 } break; 11371 11372 case GRANT_RUNTIME: { 11373 // Grant previously granted runtime permissions. 11374 for (int userId : UserManagerService.getInstance().getUserIds()) { 11375 PermissionState permissionState = origPermissions 11376 .getRuntimePermissionState(bp.name, userId); 11377 int flags = permissionState != null 11378 ? permissionState.getFlags() : 0; 11379 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 11380 // Don't propagate the permission in a permission review mode if 11381 // the former was revoked, i.e. marked to not propagate on upgrade. 11382 // Note that in a permission review mode install permissions are 11383 // represented as constantly granted runtime ones since we need to 11384 // keep a per user state associated with the permission. Also the 11385 // revoke on upgrade flag is no longer applicable and is reset. 11386 final boolean revokeOnUpgrade = (flags & PackageManager 11387 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 11388 if (revokeOnUpgrade) { 11389 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 11390 // Since we changed the flags, we have to write. 11391 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11392 changedRuntimePermissionUserIds, userId); 11393 } 11394 if (!mPermissionReviewRequired || !revokeOnUpgrade) { 11395 if (permissionsState.grantRuntimePermission(bp, userId) == 11396 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11397 // If we cannot put the permission as it was, 11398 // we have to write. 11399 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11400 changedRuntimePermissionUserIds, userId); 11401 } 11402 } 11403 11404 // If the app supports runtime permissions no need for a review. 11405 if (mPermissionReviewRequired 11406 && appSupportsRuntimePermissions 11407 && (flags & PackageManager 11408 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 11409 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 11410 // Since we changed the flags, we have to write. 11411 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11412 changedRuntimePermissionUserIds, userId); 11413 } 11414 } else if (mPermissionReviewRequired 11415 && !appSupportsRuntimePermissions) { 11416 // For legacy apps that need a permission review, every new 11417 // runtime permission is granted but it is pending a review. 11418 // We also need to review only platform defined runtime 11419 // permissions as these are the only ones the platform knows 11420 // how to disable the API to simulate revocation as legacy 11421 // apps don't expect to run with revoked permissions. 11422 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 11423 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 11424 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 11425 // We changed the flags, hence have to write. 11426 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11427 changedRuntimePermissionUserIds, userId); 11428 } 11429 } 11430 if (permissionsState.grantRuntimePermission(bp, userId) 11431 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 11432 // We changed the permission, hence have to write. 11433 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11434 changedRuntimePermissionUserIds, userId); 11435 } 11436 } 11437 // Propagate the permission flags. 11438 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 11439 } 11440 } break; 11441 11442 case GRANT_UPGRADE: { 11443 // Grant runtime permissions for a previously held install permission. 11444 PermissionState permissionState = origPermissions 11445 .getInstallPermissionState(bp.name); 11446 final int flags = permissionState != null ? permissionState.getFlags() : 0; 11447 11448 if (origPermissions.revokeInstallPermission(bp) 11449 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 11450 // We will be transferring the permission flags, so clear them. 11451 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 11452 PackageManager.MASK_PERMISSION_FLAGS, 0); 11453 changedInstallPermission = true; 11454 } 11455 11456 // If the permission is not to be promoted to runtime we ignore it and 11457 // also its other flags as they are not applicable to install permissions. 11458 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 11459 for (int userId : currentUserIds) { 11460 if (permissionsState.grantRuntimePermission(bp, userId) != 11461 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11462 // Transfer the permission flags. 11463 permissionsState.updatePermissionFlags(bp, userId, 11464 flags, flags); 11465 // If we granted the permission, we have to write. 11466 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11467 changedRuntimePermissionUserIds, userId); 11468 } 11469 } 11470 } 11471 } break; 11472 11473 default: { 11474 if (packageOfInterest == null 11475 || packageOfInterest.equals(pkg.packageName)) { 11476 Slog.w(TAG, "Not granting permission " + perm 11477 + " to package " + pkg.packageName 11478 + " because it was previously installed without"); 11479 } 11480 } break; 11481 } 11482 } else { 11483 if (permissionsState.revokeInstallPermission(bp) != 11484 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11485 // Also drop the permission flags. 11486 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 11487 PackageManager.MASK_PERMISSION_FLAGS, 0); 11488 changedInstallPermission = true; 11489 Slog.i(TAG, "Un-granting permission " + perm 11490 + " from package " + pkg.packageName 11491 + " (protectionLevel=" + bp.protectionLevel 11492 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 11493 + ")"); 11494 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 11495 // Don't print warning for app op permissions, since it is fine for them 11496 // not to be granted, there is a UI for the user to decide. 11497 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 11498 Slog.w(TAG, "Not granting permission " + perm 11499 + " to package " + pkg.packageName 11500 + " (protectionLevel=" + bp.protectionLevel 11501 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 11502 + ")"); 11503 } 11504 } 11505 } 11506 } 11507 11508 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 11509 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 11510 // This is the first that we have heard about this package, so the 11511 // permissions we have now selected are fixed until explicitly 11512 // changed. 11513 ps.installPermissionsFixed = true; 11514 } 11515 11516 // Persist the runtime permissions state for users with changes. If permissions 11517 // were revoked because no app in the shared user declares them we have to 11518 // write synchronously to avoid losing runtime permissions state. 11519 for (int userId : changedRuntimePermissionUserIds) { 11520 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 11521 } 11522 } 11523 11524 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 11525 boolean allowed = false; 11526 final int NP = PackageParser.NEW_PERMISSIONS.length; 11527 for (int ip=0; ip<NP; ip++) { 11528 final PackageParser.NewPermissionInfo npi 11529 = PackageParser.NEW_PERMISSIONS[ip]; 11530 if (npi.name.equals(perm) 11531 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 11532 allowed = true; 11533 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 11534 + pkg.packageName); 11535 break; 11536 } 11537 } 11538 return allowed; 11539 } 11540 11541 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 11542 BasePermission bp, PermissionsState origPermissions) { 11543 boolean privilegedPermission = (bp.protectionLevel 11544 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0; 11545 boolean privappPermissionsDisable = 11546 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE; 11547 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage); 11548 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName); 11549 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp() 11550 && !platformPackage && platformPermission) { 11551 ArraySet<String> wlPermissions = SystemConfig.getInstance() 11552 .getPrivAppPermissions(pkg.packageName); 11553 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm); 11554 if (!whitelisted) { 11555 Slog.w(TAG, "Privileged permission " + perm + " for package " 11556 + pkg.packageName + " - not in privapp-permissions whitelist"); 11557 if (!mSystemReady) { 11558 if (mPrivappPermissionsViolations == null) { 11559 mPrivappPermissionsViolations = new ArraySet<>(); 11560 } 11561 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm); 11562 } 11563 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { 11564 return false; 11565 } 11566 } 11567 } 11568 boolean allowed = (compareSignatures( 11569 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 11570 == PackageManager.SIGNATURE_MATCH) 11571 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 11572 == PackageManager.SIGNATURE_MATCH); 11573 if (!allowed && privilegedPermission) { 11574 if (isSystemApp(pkg)) { 11575 // For updated system applications, a system permission 11576 // is granted only if it had been defined by the original application. 11577 if (pkg.isUpdatedSystemApp()) { 11578 final PackageSetting sysPs = mSettings 11579 .getDisabledSystemPkgLPr(pkg.packageName); 11580 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 11581 // If the original was granted this permission, we take 11582 // that grant decision as read and propagate it to the 11583 // update. 11584 if (sysPs.isPrivileged()) { 11585 allowed = true; 11586 } 11587 } else { 11588 // The system apk may have been updated with an older 11589 // version of the one on the data partition, but which 11590 // granted a new system permission that it didn't have 11591 // before. In this case we do want to allow the app to 11592 // now get the new permission if the ancestral apk is 11593 // privileged to get it. 11594 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 11595 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 11596 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 11597 allowed = true; 11598 break; 11599 } 11600 } 11601 } 11602 // Also if a privileged parent package on the system image or any of 11603 // its children requested a privileged permission, the updated child 11604 // packages can also get the permission. 11605 if (pkg.parentPackage != null) { 11606 final PackageSetting disabledSysParentPs = mSettings 11607 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 11608 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 11609 && disabledSysParentPs.isPrivileged()) { 11610 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 11611 allowed = true; 11612 } else if (disabledSysParentPs.pkg.childPackages != null) { 11613 final int count = disabledSysParentPs.pkg.childPackages.size(); 11614 for (int i = 0; i < count; i++) { 11615 PackageParser.Package disabledSysChildPkg = 11616 disabledSysParentPs.pkg.childPackages.get(i); 11617 if (isPackageRequestingPermission(disabledSysChildPkg, 11618 perm)) { 11619 allowed = true; 11620 break; 11621 } 11622 } 11623 } 11624 } 11625 } 11626 } 11627 } else { 11628 allowed = isPrivilegedApp(pkg); 11629 } 11630 } 11631 } 11632 if (!allowed) { 11633 if (!allowed && (bp.protectionLevel 11634 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 11635 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 11636 // If this was a previously normal/dangerous permission that got moved 11637 // to a system permission as part of the runtime permission redesign, then 11638 // we still want to blindly grant it to old apps. 11639 allowed = true; 11640 } 11641 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 11642 && pkg.packageName.equals(mRequiredInstallerPackage)) { 11643 // If this permission is to be granted to the system installer and 11644 // this app is an installer, then it gets the permission. 11645 allowed = true; 11646 } 11647 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 11648 && pkg.packageName.equals(mRequiredVerifierPackage)) { 11649 // If this permission is to be granted to the system verifier and 11650 // this app is a verifier, then it gets the permission. 11651 allowed = true; 11652 } 11653 if (!allowed && (bp.protectionLevel 11654 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 11655 && isSystemApp(pkg)) { 11656 // Any pre-installed system app is allowed to get this permission. 11657 allowed = true; 11658 } 11659 if (!allowed && (bp.protectionLevel 11660 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 11661 // For development permissions, a development permission 11662 // is granted only if it was already granted. 11663 allowed = origPermissions.hasInstallPermission(perm); 11664 } 11665 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 11666 && pkg.packageName.equals(mSetupWizardPackage)) { 11667 // If this permission is to be granted to the system setup wizard and 11668 // this app is a setup wizard, then it gets the permission. 11669 allowed = true; 11670 } 11671 } 11672 return allowed; 11673 } 11674 11675 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 11676 final int permCount = pkg.requestedPermissions.size(); 11677 for (int j = 0; j < permCount; j++) { 11678 String requestedPermission = pkg.requestedPermissions.get(j); 11679 if (permission.equals(requestedPermission)) { 11680 return true; 11681 } 11682 } 11683 return false; 11684 } 11685 11686 final class ActivityIntentResolver 11687 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 11688 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11689 boolean defaultOnly, int userId) { 11690 if (!sUserManager.exists(userId)) return null; 11691 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0); 11692 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11693 } 11694 11695 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11696 int userId) { 11697 if (!sUserManager.exists(userId)) return null; 11698 mFlags = flags; 11699 return super.queryIntent(intent, resolvedType, 11700 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 11701 userId); 11702 } 11703 11704 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11705 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 11706 if (!sUserManager.exists(userId)) return null; 11707 if (packageActivities == null) { 11708 return null; 11709 } 11710 mFlags = flags; 11711 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11712 final int N = packageActivities.size(); 11713 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 11714 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 11715 11716 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 11717 for (int i = 0; i < N; ++i) { 11718 intentFilters = packageActivities.get(i).intents; 11719 if (intentFilters != null && intentFilters.size() > 0) { 11720 PackageParser.ActivityIntentInfo[] array = 11721 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 11722 intentFilters.toArray(array); 11723 listCut.add(array); 11724 } 11725 } 11726 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11727 } 11728 11729 /** 11730 * Finds a privileged activity that matches the specified activity names. 11731 */ 11732 private PackageParser.Activity findMatchingActivity( 11733 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 11734 for (PackageParser.Activity sysActivity : activityList) { 11735 if (sysActivity.info.name.equals(activityInfo.name)) { 11736 return sysActivity; 11737 } 11738 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 11739 return sysActivity; 11740 } 11741 if (sysActivity.info.targetActivity != null) { 11742 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 11743 return sysActivity; 11744 } 11745 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 11746 return sysActivity; 11747 } 11748 } 11749 } 11750 return null; 11751 } 11752 11753 public class IterGenerator<E> { 11754 public Iterator<E> generate(ActivityIntentInfo info) { 11755 return null; 11756 } 11757 } 11758 11759 public class ActionIterGenerator extends IterGenerator<String> { 11760 @Override 11761 public Iterator<String> generate(ActivityIntentInfo info) { 11762 return info.actionsIterator(); 11763 } 11764 } 11765 11766 public class CategoriesIterGenerator extends IterGenerator<String> { 11767 @Override 11768 public Iterator<String> generate(ActivityIntentInfo info) { 11769 return info.categoriesIterator(); 11770 } 11771 } 11772 11773 public class SchemesIterGenerator extends IterGenerator<String> { 11774 @Override 11775 public Iterator<String> generate(ActivityIntentInfo info) { 11776 return info.schemesIterator(); 11777 } 11778 } 11779 11780 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 11781 @Override 11782 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 11783 return info.authoritiesIterator(); 11784 } 11785 } 11786 11787 /** 11788 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 11789 * MODIFIED. Do not pass in a list that should not be changed. 11790 */ 11791 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 11792 IterGenerator<T> generator, Iterator<T> searchIterator) { 11793 // loop through the set of actions; every one must be found in the intent filter 11794 while (searchIterator.hasNext()) { 11795 // we must have at least one filter in the list to consider a match 11796 if (intentList.size() == 0) { 11797 break; 11798 } 11799 11800 final T searchAction = searchIterator.next(); 11801 11802 // loop through the set of intent filters 11803 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 11804 while (intentIter.hasNext()) { 11805 final ActivityIntentInfo intentInfo = intentIter.next(); 11806 boolean selectionFound = false; 11807 11808 // loop through the intent filter's selection criteria; at least one 11809 // of them must match the searched criteria 11810 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 11811 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 11812 final T intentSelection = intentSelectionIter.next(); 11813 if (intentSelection != null && intentSelection.equals(searchAction)) { 11814 selectionFound = true; 11815 break; 11816 } 11817 } 11818 11819 // the selection criteria wasn't found in this filter's set; this filter 11820 // is not a potential match 11821 if (!selectionFound) { 11822 intentIter.remove(); 11823 } 11824 } 11825 } 11826 } 11827 11828 private boolean isProtectedAction(ActivityIntentInfo filter) { 11829 final Iterator<String> actionsIter = filter.actionsIterator(); 11830 while (actionsIter != null && actionsIter.hasNext()) { 11831 final String filterAction = actionsIter.next(); 11832 if (PROTECTED_ACTIONS.contains(filterAction)) { 11833 return true; 11834 } 11835 } 11836 return false; 11837 } 11838 11839 /** 11840 * Adjusts the priority of the given intent filter according to policy. 11841 * <p> 11842 * <ul> 11843 * <li>The priority for non privileged applications is capped to '0'</li> 11844 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 11845 * <li>The priority for unbundled updates to privileged applications is capped to the 11846 * priority defined on the system partition</li> 11847 * </ul> 11848 * <p> 11849 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 11850 * allowed to obtain any priority on any action. 11851 */ 11852 private void adjustPriority( 11853 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 11854 // nothing to do; priority is fine as-is 11855 if (intent.getPriority() <= 0) { 11856 return; 11857 } 11858 11859 final ActivityInfo activityInfo = intent.activity.info; 11860 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 11861 11862 final boolean privilegedApp = 11863 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 11864 if (!privilegedApp) { 11865 // non-privileged applications can never define a priority >0 11866 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 11867 + " package: " + applicationInfo.packageName 11868 + " activity: " + intent.activity.className 11869 + " origPrio: " + intent.getPriority()); 11870 intent.setPriority(0); 11871 return; 11872 } 11873 11874 if (systemActivities == null) { 11875 // the system package is not disabled; we're parsing the system partition 11876 if (isProtectedAction(intent)) { 11877 if (mDeferProtectedFilters) { 11878 // We can't deal with these just yet. No component should ever obtain a 11879 // >0 priority for a protected actions, with ONE exception -- the setup 11880 // wizard. The setup wizard, however, cannot be known until we're able to 11881 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 11882 // until all intent filters have been processed. Chicken, meet egg. 11883 // Let the filter temporarily have a high priority and rectify the 11884 // priorities after all system packages have been scanned. 11885 mProtectedFilters.add(intent); 11886 if (DEBUG_FILTERS) { 11887 Slog.i(TAG, "Protected action; save for later;" 11888 + " package: " + applicationInfo.packageName 11889 + " activity: " + intent.activity.className 11890 + " origPrio: " + intent.getPriority()); 11891 } 11892 return; 11893 } else { 11894 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 11895 Slog.i(TAG, "No setup wizard;" 11896 + " All protected intents capped to priority 0"); 11897 } 11898 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 11899 if (DEBUG_FILTERS) { 11900 Slog.i(TAG, "Found setup wizard;" 11901 + " allow priority " + intent.getPriority() + ";" 11902 + " package: " + intent.activity.info.packageName 11903 + " activity: " + intent.activity.className 11904 + " priority: " + intent.getPriority()); 11905 } 11906 // setup wizard gets whatever it wants 11907 return; 11908 } 11909 Slog.w(TAG, "Protected action; cap priority to 0;" 11910 + " package: " + intent.activity.info.packageName 11911 + " activity: " + intent.activity.className 11912 + " origPrio: " + intent.getPriority()); 11913 intent.setPriority(0); 11914 return; 11915 } 11916 } 11917 // privileged apps on the system image get whatever priority they request 11918 return; 11919 } 11920 11921 // privileged app unbundled update ... try to find the same activity 11922 final PackageParser.Activity foundActivity = 11923 findMatchingActivity(systemActivities, activityInfo); 11924 if (foundActivity == null) { 11925 // this is a new activity; it cannot obtain >0 priority 11926 if (DEBUG_FILTERS) { 11927 Slog.i(TAG, "New activity; cap priority to 0;" 11928 + " package: " + applicationInfo.packageName 11929 + " activity: " + intent.activity.className 11930 + " origPrio: " + intent.getPriority()); 11931 } 11932 intent.setPriority(0); 11933 return; 11934 } 11935 11936 // found activity, now check for filter equivalence 11937 11938 // a shallow copy is enough; we modify the list, not its contents 11939 final List<ActivityIntentInfo> intentListCopy = 11940 new ArrayList<>(foundActivity.intents); 11941 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 11942 11943 // find matching action subsets 11944 final Iterator<String> actionsIterator = intent.actionsIterator(); 11945 if (actionsIterator != null) { 11946 getIntentListSubset( 11947 intentListCopy, new ActionIterGenerator(), actionsIterator); 11948 if (intentListCopy.size() == 0) { 11949 // no more intents to match; we're not equivalent 11950 if (DEBUG_FILTERS) { 11951 Slog.i(TAG, "Mismatched action; cap priority to 0;" 11952 + " package: " + applicationInfo.packageName 11953 + " activity: " + intent.activity.className 11954 + " origPrio: " + intent.getPriority()); 11955 } 11956 intent.setPriority(0); 11957 return; 11958 } 11959 } 11960 11961 // find matching category subsets 11962 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 11963 if (categoriesIterator != null) { 11964 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 11965 categoriesIterator); 11966 if (intentListCopy.size() == 0) { 11967 // no more intents to match; we're not equivalent 11968 if (DEBUG_FILTERS) { 11969 Slog.i(TAG, "Mismatched category; cap priority to 0;" 11970 + " package: " + applicationInfo.packageName 11971 + " activity: " + intent.activity.className 11972 + " origPrio: " + intent.getPriority()); 11973 } 11974 intent.setPriority(0); 11975 return; 11976 } 11977 } 11978 11979 // find matching schemes subsets 11980 final Iterator<String> schemesIterator = intent.schemesIterator(); 11981 if (schemesIterator != null) { 11982 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 11983 schemesIterator); 11984 if (intentListCopy.size() == 0) { 11985 // no more intents to match; we're not equivalent 11986 if (DEBUG_FILTERS) { 11987 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 11988 + " package: " + applicationInfo.packageName 11989 + " activity: " + intent.activity.className 11990 + " origPrio: " + intent.getPriority()); 11991 } 11992 intent.setPriority(0); 11993 return; 11994 } 11995 } 11996 11997 // find matching authorities subsets 11998 final Iterator<IntentFilter.AuthorityEntry> 11999 authoritiesIterator = intent.authoritiesIterator(); 12000 if (authoritiesIterator != null) { 12001 getIntentListSubset(intentListCopy, 12002 new AuthoritiesIterGenerator(), 12003 authoritiesIterator); 12004 if (intentListCopy.size() == 0) { 12005 // no more intents to match; we're not equivalent 12006 if (DEBUG_FILTERS) { 12007 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 12008 + " package: " + applicationInfo.packageName 12009 + " activity: " + intent.activity.className 12010 + " origPrio: " + intent.getPriority()); 12011 } 12012 intent.setPriority(0); 12013 return; 12014 } 12015 } 12016 12017 // we found matching filter(s); app gets the max priority of all intents 12018 int cappedPriority = 0; 12019 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 12020 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 12021 } 12022 if (intent.getPriority() > cappedPriority) { 12023 if (DEBUG_FILTERS) { 12024 Slog.i(TAG, "Found matching filter(s);" 12025 + " cap priority to " + cappedPriority + ";" 12026 + " package: " + applicationInfo.packageName 12027 + " activity: " + intent.activity.className 12028 + " origPrio: " + intent.getPriority()); 12029 } 12030 intent.setPriority(cappedPriority); 12031 return; 12032 } 12033 // all this for nothing; the requested priority was <= what was on the system 12034 } 12035 12036 public final void addActivity(PackageParser.Activity a, String type) { 12037 mActivities.put(a.getComponentName(), a); 12038 if (DEBUG_SHOW_INFO) 12039 Log.v( 12040 TAG, " " + type + " " + 12041 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 12042 if (DEBUG_SHOW_INFO) 12043 Log.v(TAG, " Class=" + a.info.name); 12044 final int NI = a.intents.size(); 12045 for (int j=0; j<NI; j++) { 12046 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 12047 if ("activity".equals(type)) { 12048 final PackageSetting ps = 12049 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 12050 final List<PackageParser.Activity> systemActivities = 12051 ps != null && ps.pkg != null ? ps.pkg.activities : null; 12052 adjustPriority(systemActivities, intent); 12053 } 12054 if (DEBUG_SHOW_INFO) { 12055 Log.v(TAG, " IntentFilter:"); 12056 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12057 } 12058 if (!intent.debugCheck()) { 12059 Log.w(TAG, "==> For Activity " + a.info.name); 12060 } 12061 addFilter(intent); 12062 } 12063 } 12064 12065 public final void removeActivity(PackageParser.Activity a, String type) { 12066 mActivities.remove(a.getComponentName()); 12067 if (DEBUG_SHOW_INFO) { 12068 Log.v(TAG, " " + type + " " 12069 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 12070 : a.info.name) + ":"); 12071 Log.v(TAG, " Class=" + a.info.name); 12072 } 12073 final int NI = a.intents.size(); 12074 for (int j=0; j<NI; j++) { 12075 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 12076 if (DEBUG_SHOW_INFO) { 12077 Log.v(TAG, " IntentFilter:"); 12078 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12079 } 12080 removeFilter(intent); 12081 } 12082 } 12083 12084 @Override 12085 protected boolean allowFilterResult( 12086 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 12087 ActivityInfo filterAi = filter.activity.info; 12088 for (int i=dest.size()-1; i>=0; i--) { 12089 ActivityInfo destAi = dest.get(i).activityInfo; 12090 if (destAi.name == filterAi.name 12091 && destAi.packageName == filterAi.packageName) { 12092 return false; 12093 } 12094 } 12095 return true; 12096 } 12097 12098 @Override 12099 protected ActivityIntentInfo[] newArray(int size) { 12100 return new ActivityIntentInfo[size]; 12101 } 12102 12103 @Override 12104 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 12105 if (!sUserManager.exists(userId)) return true; 12106 PackageParser.Package p = filter.activity.owner; 12107 if (p != null) { 12108 PackageSetting ps = (PackageSetting)p.mExtras; 12109 if (ps != null) { 12110 // System apps are never considered stopped for purposes of 12111 // filtering, because there may be no way for the user to 12112 // actually re-launch them. 12113 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 12114 && ps.getStopped(userId); 12115 } 12116 } 12117 return false; 12118 } 12119 12120 @Override 12121 protected boolean isPackageForFilter(String packageName, 12122 PackageParser.ActivityIntentInfo info) { 12123 return packageName.equals(info.activity.owner.packageName); 12124 } 12125 12126 @Override 12127 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 12128 int match, int userId) { 12129 if (!sUserManager.exists(userId)) return null; 12130 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 12131 return null; 12132 } 12133 final PackageParser.Activity activity = info.activity; 12134 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 12135 if (ps == null) { 12136 return null; 12137 } 12138 final PackageUserState userState = ps.readUserState(userId); 12139 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 12140 userState, userId); 12141 if (ai == null) { 12142 return null; 12143 } 12144 final boolean matchVisibleToInstantApp = 12145 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; 12146 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0; 12147 // throw out filters that aren't visible to ephemeral apps 12148 if (matchVisibleToInstantApp 12149 && !(info.isVisibleToInstantApp() || userState.instantApp)) { 12150 return null; 12151 } 12152 // throw out ephemeral filters if we're not explicitly requesting them 12153 if (!isInstantApp && userState.instantApp) { 12154 return null; 12155 } 12156 final ResolveInfo res = new ResolveInfo(); 12157 res.activityInfo = ai; 12158 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 12159 res.filter = info; 12160 } 12161 if (info != null) { 12162 res.handleAllWebDataURI = info.handleAllWebDataURI(); 12163 } 12164 res.priority = info.getPriority(); 12165 res.preferredOrder = activity.owner.mPreferredOrder; 12166 //System.out.println("Result: " + res.activityInfo.className + 12167 // " = " + res.priority); 12168 res.match = match; 12169 res.isDefault = info.hasDefault; 12170 res.labelRes = info.labelRes; 12171 res.nonLocalizedLabel = info.nonLocalizedLabel; 12172 if (userNeedsBadging(userId)) { 12173 res.noResourceId = true; 12174 } else { 12175 res.icon = info.icon; 12176 } 12177 res.iconResourceId = info.icon; 12178 res.system = res.activityInfo.applicationInfo.isSystemApp(); 12179 return res; 12180 } 12181 12182 @Override 12183 protected void sortResults(List<ResolveInfo> results) { 12184 Collections.sort(results, mResolvePrioritySorter); 12185 } 12186 12187 @Override 12188 protected void dumpFilter(PrintWriter out, String prefix, 12189 PackageParser.ActivityIntentInfo filter) { 12190 out.print(prefix); out.print( 12191 Integer.toHexString(System.identityHashCode(filter.activity))); 12192 out.print(' '); 12193 filter.activity.printComponentShortName(out); 12194 out.print(" filter "); 12195 out.println(Integer.toHexString(System.identityHashCode(filter))); 12196 } 12197 12198 @Override 12199 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 12200 return filter.activity; 12201 } 12202 12203 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12204 PackageParser.Activity activity = (PackageParser.Activity)label; 12205 out.print(prefix); out.print( 12206 Integer.toHexString(System.identityHashCode(activity))); 12207 out.print(' '); 12208 activity.printComponentShortName(out); 12209 if (count > 1) { 12210 out.print(" ("); out.print(count); out.print(" filters)"); 12211 } 12212 out.println(); 12213 } 12214 12215 // Keys are String (activity class name), values are Activity. 12216 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 12217 = new ArrayMap<ComponentName, PackageParser.Activity>(); 12218 private int mFlags; 12219 } 12220 12221 private final class ServiceIntentResolver 12222 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 12223 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 12224 boolean defaultOnly, int userId) { 12225 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 12226 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 12227 } 12228 12229 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 12230 int userId) { 12231 if (!sUserManager.exists(userId)) return null; 12232 mFlags = flags; 12233 return super.queryIntent(intent, resolvedType, 12234 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 12235 userId); 12236 } 12237 12238 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 12239 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 12240 if (!sUserManager.exists(userId)) return null; 12241 if (packageServices == null) { 12242 return null; 12243 } 12244 mFlags = flags; 12245 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 12246 final int N = packageServices.size(); 12247 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 12248 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 12249 12250 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 12251 for (int i = 0; i < N; ++i) { 12252 intentFilters = packageServices.get(i).intents; 12253 if (intentFilters != null && intentFilters.size() > 0) { 12254 PackageParser.ServiceIntentInfo[] array = 12255 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 12256 intentFilters.toArray(array); 12257 listCut.add(array); 12258 } 12259 } 12260 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 12261 } 12262 12263 public final void addService(PackageParser.Service s) { 12264 mServices.put(s.getComponentName(), s); 12265 if (DEBUG_SHOW_INFO) { 12266 Log.v(TAG, " " 12267 + (s.info.nonLocalizedLabel != null 12268 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 12269 Log.v(TAG, " Class=" + s.info.name); 12270 } 12271 final int NI = s.intents.size(); 12272 int j; 12273 for (j=0; j<NI; j++) { 12274 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 12275 if (DEBUG_SHOW_INFO) { 12276 Log.v(TAG, " IntentFilter:"); 12277 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12278 } 12279 if (!intent.debugCheck()) { 12280 Log.w(TAG, "==> For Service " + s.info.name); 12281 } 12282 addFilter(intent); 12283 } 12284 } 12285 12286 public final void removeService(PackageParser.Service s) { 12287 mServices.remove(s.getComponentName()); 12288 if (DEBUG_SHOW_INFO) { 12289 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 12290 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 12291 Log.v(TAG, " Class=" + s.info.name); 12292 } 12293 final int NI = s.intents.size(); 12294 int j; 12295 for (j=0; j<NI; j++) { 12296 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 12297 if (DEBUG_SHOW_INFO) { 12298 Log.v(TAG, " IntentFilter:"); 12299 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12300 } 12301 removeFilter(intent); 12302 } 12303 } 12304 12305 @Override 12306 protected boolean allowFilterResult( 12307 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 12308 ServiceInfo filterSi = filter.service.info; 12309 for (int i=dest.size()-1; i>=0; i--) { 12310 ServiceInfo destAi = dest.get(i).serviceInfo; 12311 if (destAi.name == filterSi.name 12312 && destAi.packageName == filterSi.packageName) { 12313 return false; 12314 } 12315 } 12316 return true; 12317 } 12318 12319 @Override 12320 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 12321 return new PackageParser.ServiceIntentInfo[size]; 12322 } 12323 12324 @Override 12325 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 12326 if (!sUserManager.exists(userId)) return true; 12327 PackageParser.Package p = filter.service.owner; 12328 if (p != null) { 12329 PackageSetting ps = (PackageSetting)p.mExtras; 12330 if (ps != null) { 12331 // System apps are never considered stopped for purposes of 12332 // filtering, because there may be no way for the user to 12333 // actually re-launch them. 12334 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 12335 && ps.getStopped(userId); 12336 } 12337 } 12338 return false; 12339 } 12340 12341 @Override 12342 protected boolean isPackageForFilter(String packageName, 12343 PackageParser.ServiceIntentInfo info) { 12344 return packageName.equals(info.service.owner.packageName); 12345 } 12346 12347 @Override 12348 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 12349 int match, int userId) { 12350 if (!sUserManager.exists(userId)) return null; 12351 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 12352 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 12353 return null; 12354 } 12355 final PackageParser.Service service = info.service; 12356 PackageSetting ps = (PackageSetting) service.owner.mExtras; 12357 if (ps == null) { 12358 return null; 12359 } 12360 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 12361 ps.readUserState(userId), userId); 12362 if (si == null) { 12363 return null; 12364 } 12365 final ResolveInfo res = new ResolveInfo(); 12366 res.serviceInfo = si; 12367 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 12368 res.filter = filter; 12369 } 12370 res.priority = info.getPriority(); 12371 res.preferredOrder = service.owner.mPreferredOrder; 12372 res.match = match; 12373 res.isDefault = info.hasDefault; 12374 res.labelRes = info.labelRes; 12375 res.nonLocalizedLabel = info.nonLocalizedLabel; 12376 res.icon = info.icon; 12377 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 12378 return res; 12379 } 12380 12381 @Override 12382 protected void sortResults(List<ResolveInfo> results) { 12383 Collections.sort(results, mResolvePrioritySorter); 12384 } 12385 12386 @Override 12387 protected void dumpFilter(PrintWriter out, String prefix, 12388 PackageParser.ServiceIntentInfo filter) { 12389 out.print(prefix); out.print( 12390 Integer.toHexString(System.identityHashCode(filter.service))); 12391 out.print(' '); 12392 filter.service.printComponentShortName(out); 12393 out.print(" filter "); 12394 out.println(Integer.toHexString(System.identityHashCode(filter))); 12395 } 12396 12397 @Override 12398 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 12399 return filter.service; 12400 } 12401 12402 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12403 PackageParser.Service service = (PackageParser.Service)label; 12404 out.print(prefix); out.print( 12405 Integer.toHexString(System.identityHashCode(service))); 12406 out.print(' '); 12407 service.printComponentShortName(out); 12408 if (count > 1) { 12409 out.print(" ("); out.print(count); out.print(" filters)"); 12410 } 12411 out.println(); 12412 } 12413 12414// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 12415// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 12416// final List<ResolveInfo> retList = Lists.newArrayList(); 12417// while (i.hasNext()) { 12418// final ResolveInfo resolveInfo = (ResolveInfo) i; 12419// if (isEnabledLP(resolveInfo.serviceInfo)) { 12420// retList.add(resolveInfo); 12421// } 12422// } 12423// return retList; 12424// } 12425 12426 // Keys are String (activity class name), values are Activity. 12427 private final ArrayMap<ComponentName, PackageParser.Service> mServices 12428 = new ArrayMap<ComponentName, PackageParser.Service>(); 12429 private int mFlags; 12430 } 12431 12432 private final class ProviderIntentResolver 12433 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 12434 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 12435 boolean defaultOnly, int userId) { 12436 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 12437 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 12438 } 12439 12440 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 12441 int userId) { 12442 if (!sUserManager.exists(userId)) 12443 return null; 12444 mFlags = flags; 12445 return super.queryIntent(intent, resolvedType, 12446 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 12447 userId); 12448 } 12449 12450 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 12451 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 12452 if (!sUserManager.exists(userId)) 12453 return null; 12454 if (packageProviders == null) { 12455 return null; 12456 } 12457 mFlags = flags; 12458 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 12459 final int N = packageProviders.size(); 12460 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 12461 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 12462 12463 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 12464 for (int i = 0; i < N; ++i) { 12465 intentFilters = packageProviders.get(i).intents; 12466 if (intentFilters != null && intentFilters.size() > 0) { 12467 PackageParser.ProviderIntentInfo[] array = 12468 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 12469 intentFilters.toArray(array); 12470 listCut.add(array); 12471 } 12472 } 12473 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 12474 } 12475 12476 public final void addProvider(PackageParser.Provider p) { 12477 if (mProviders.containsKey(p.getComponentName())) { 12478 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 12479 return; 12480 } 12481 12482 mProviders.put(p.getComponentName(), p); 12483 if (DEBUG_SHOW_INFO) { 12484 Log.v(TAG, " " 12485 + (p.info.nonLocalizedLabel != null 12486 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 12487 Log.v(TAG, " Class=" + p.info.name); 12488 } 12489 final int NI = p.intents.size(); 12490 int j; 12491 for (j = 0; j < NI; j++) { 12492 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 12493 if (DEBUG_SHOW_INFO) { 12494 Log.v(TAG, " IntentFilter:"); 12495 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12496 } 12497 if (!intent.debugCheck()) { 12498 Log.w(TAG, "==> For Provider " + p.info.name); 12499 } 12500 addFilter(intent); 12501 } 12502 } 12503 12504 public final void removeProvider(PackageParser.Provider p) { 12505 mProviders.remove(p.getComponentName()); 12506 if (DEBUG_SHOW_INFO) { 12507 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 12508 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 12509 Log.v(TAG, " Class=" + p.info.name); 12510 } 12511 final int NI = p.intents.size(); 12512 int j; 12513 for (j = 0; j < NI; j++) { 12514 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 12515 if (DEBUG_SHOW_INFO) { 12516 Log.v(TAG, " IntentFilter:"); 12517 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12518 } 12519 removeFilter(intent); 12520 } 12521 } 12522 12523 @Override 12524 protected boolean allowFilterResult( 12525 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 12526 ProviderInfo filterPi = filter.provider.info; 12527 for (int i = dest.size() - 1; i >= 0; i--) { 12528 ProviderInfo destPi = dest.get(i).providerInfo; 12529 if (destPi.name == filterPi.name 12530 && destPi.packageName == filterPi.packageName) { 12531 return false; 12532 } 12533 } 12534 return true; 12535 } 12536 12537 @Override 12538 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 12539 return new PackageParser.ProviderIntentInfo[size]; 12540 } 12541 12542 @Override 12543 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 12544 if (!sUserManager.exists(userId)) 12545 return true; 12546 PackageParser.Package p = filter.provider.owner; 12547 if (p != null) { 12548 PackageSetting ps = (PackageSetting) p.mExtras; 12549 if (ps != null) { 12550 // System apps are never considered stopped for purposes of 12551 // filtering, because there may be no way for the user to 12552 // actually re-launch them. 12553 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 12554 && ps.getStopped(userId); 12555 } 12556 } 12557 return false; 12558 } 12559 12560 @Override 12561 protected boolean isPackageForFilter(String packageName, 12562 PackageParser.ProviderIntentInfo info) { 12563 return packageName.equals(info.provider.owner.packageName); 12564 } 12565 12566 @Override 12567 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 12568 int match, int userId) { 12569 if (!sUserManager.exists(userId)) 12570 return null; 12571 final PackageParser.ProviderIntentInfo info = filter; 12572 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 12573 return null; 12574 } 12575 final PackageParser.Provider provider = info.provider; 12576 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 12577 if (ps == null) { 12578 return null; 12579 } 12580 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 12581 ps.readUserState(userId), userId); 12582 if (pi == null) { 12583 return null; 12584 } 12585 final ResolveInfo res = new ResolveInfo(); 12586 res.providerInfo = pi; 12587 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 12588 res.filter = filter; 12589 } 12590 res.priority = info.getPriority(); 12591 res.preferredOrder = provider.owner.mPreferredOrder; 12592 res.match = match; 12593 res.isDefault = info.hasDefault; 12594 res.labelRes = info.labelRes; 12595 res.nonLocalizedLabel = info.nonLocalizedLabel; 12596 res.icon = info.icon; 12597 res.system = res.providerInfo.applicationInfo.isSystemApp(); 12598 return res; 12599 } 12600 12601 @Override 12602 protected void sortResults(List<ResolveInfo> results) { 12603 Collections.sort(results, mResolvePrioritySorter); 12604 } 12605 12606 @Override 12607 protected void dumpFilter(PrintWriter out, String prefix, 12608 PackageParser.ProviderIntentInfo filter) { 12609 out.print(prefix); 12610 out.print( 12611 Integer.toHexString(System.identityHashCode(filter.provider))); 12612 out.print(' '); 12613 filter.provider.printComponentShortName(out); 12614 out.print(" filter "); 12615 out.println(Integer.toHexString(System.identityHashCode(filter))); 12616 } 12617 12618 @Override 12619 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 12620 return filter.provider; 12621 } 12622 12623 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12624 PackageParser.Provider provider = (PackageParser.Provider)label; 12625 out.print(prefix); out.print( 12626 Integer.toHexString(System.identityHashCode(provider))); 12627 out.print(' '); 12628 provider.printComponentShortName(out); 12629 if (count > 1) { 12630 out.print(" ("); out.print(count); out.print(" filters)"); 12631 } 12632 out.println(); 12633 } 12634 12635 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 12636 = new ArrayMap<ComponentName, PackageParser.Provider>(); 12637 private int mFlags; 12638 } 12639 12640 static final class EphemeralIntentResolver 12641 extends IntentResolver<EphemeralResponse, EphemeralResponse> { 12642 /** 12643 * The result that has the highest defined order. Ordering applies on a 12644 * per-package basis. Mapping is from package name to Pair of order and 12645 * EphemeralResolveInfo. 12646 * <p> 12647 * NOTE: This is implemented as a field variable for convenience and efficiency. 12648 * By having a field variable, we're able to track filter ordering as soon as 12649 * a non-zero order is defined. Otherwise, multiple loops across the result set 12650 * would be needed to apply ordering. If the intent resolver becomes re-entrant, 12651 * this needs to be contained entirely within {@link #filterResults()}. 12652 */ 12653 final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>(); 12654 12655 @Override 12656 protected EphemeralResponse[] newArray(int size) { 12657 return new EphemeralResponse[size]; 12658 } 12659 12660 @Override 12661 protected boolean isPackageForFilter(String packageName, EphemeralResponse responseObj) { 12662 return true; 12663 } 12664 12665 @Override 12666 protected EphemeralResponse newResult(EphemeralResponse responseObj, int match, 12667 int userId) { 12668 if (!sUserManager.exists(userId)) { 12669 return null; 12670 } 12671 final String packageName = responseObj.resolveInfo.getPackageName(); 12672 final Integer order = responseObj.getOrder(); 12673 final Pair<Integer, EphemeralResolveInfo> lastOrderResult = 12674 mOrderResult.get(packageName); 12675 // ordering is enabled and this item's order isn't high enough 12676 if (lastOrderResult != null && lastOrderResult.first >= order) { 12677 return null; 12678 } 12679 final EphemeralResolveInfo res = responseObj.resolveInfo; 12680 if (order > 0) { 12681 // non-zero order, enable ordering 12682 mOrderResult.put(packageName, new Pair<>(order, res)); 12683 } 12684 return responseObj; 12685 } 12686 12687 @Override 12688 protected void filterResults(List<EphemeralResponse> results) { 12689 // only do work if ordering is enabled [most of the time it won't be] 12690 if (mOrderResult.size() == 0) { 12691 return; 12692 } 12693 int resultSize = results.size(); 12694 for (int i = 0; i < resultSize; i++) { 12695 final EphemeralResolveInfo info = results.get(i).resolveInfo; 12696 final String packageName = info.getPackageName(); 12697 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName); 12698 if (savedInfo == null) { 12699 // package doesn't having ordering 12700 continue; 12701 } 12702 if (savedInfo.second == info) { 12703 // circled back to the highest ordered item; remove from order list 12704 mOrderResult.remove(savedInfo); 12705 if (mOrderResult.size() == 0) { 12706 // no more ordered items 12707 break; 12708 } 12709 continue; 12710 } 12711 // item has a worse order, remove it from the result list 12712 results.remove(i); 12713 resultSize--; 12714 i--; 12715 } 12716 } 12717 } 12718 12719 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 12720 new Comparator<ResolveInfo>() { 12721 public int compare(ResolveInfo r1, ResolveInfo r2) { 12722 int v1 = r1.priority; 12723 int v2 = r2.priority; 12724 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 12725 if (v1 != v2) { 12726 return (v1 > v2) ? -1 : 1; 12727 } 12728 v1 = r1.preferredOrder; 12729 v2 = r2.preferredOrder; 12730 if (v1 != v2) { 12731 return (v1 > v2) ? -1 : 1; 12732 } 12733 if (r1.isDefault != r2.isDefault) { 12734 return r1.isDefault ? -1 : 1; 12735 } 12736 v1 = r1.match; 12737 v2 = r2.match; 12738 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 12739 if (v1 != v2) { 12740 return (v1 > v2) ? -1 : 1; 12741 } 12742 if (r1.system != r2.system) { 12743 return r1.system ? -1 : 1; 12744 } 12745 if (r1.activityInfo != null) { 12746 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 12747 } 12748 if (r1.serviceInfo != null) { 12749 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 12750 } 12751 if (r1.providerInfo != null) { 12752 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 12753 } 12754 return 0; 12755 } 12756 }; 12757 12758 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 12759 new Comparator<ProviderInfo>() { 12760 public int compare(ProviderInfo p1, ProviderInfo p2) { 12761 final int v1 = p1.initOrder; 12762 final int v2 = p2.initOrder; 12763 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 12764 } 12765 }; 12766 12767 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 12768 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 12769 final int[] userIds) { 12770 mHandler.post(new Runnable() { 12771 @Override 12772 public void run() { 12773 try { 12774 final IActivityManager am = ActivityManager.getService(); 12775 if (am == null) return; 12776 final int[] resolvedUserIds; 12777 if (userIds == null) { 12778 resolvedUserIds = am.getRunningUserIds(); 12779 } else { 12780 resolvedUserIds = userIds; 12781 } 12782 for (int id : resolvedUserIds) { 12783 final Intent intent = new Intent(action, 12784 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 12785 if (extras != null) { 12786 intent.putExtras(extras); 12787 } 12788 if (targetPkg != null) { 12789 intent.setPackage(targetPkg); 12790 } 12791 // Modify the UID when posting to other users 12792 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 12793 if (uid > 0 && UserHandle.getUserId(uid) != id) { 12794 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 12795 intent.putExtra(Intent.EXTRA_UID, uid); 12796 } 12797 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 12798 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 12799 if (DEBUG_BROADCASTS) { 12800 RuntimeException here = new RuntimeException("here"); 12801 here.fillInStackTrace(); 12802 Slog.d(TAG, "Sending to user " + id + ": " 12803 + intent.toShortString(false, true, false, false) 12804 + " " + intent.getExtras(), here); 12805 } 12806 am.broadcastIntent(null, intent, null, finishedReceiver, 12807 0, null, null, null, android.app.AppOpsManager.OP_NONE, 12808 null, finishedReceiver != null, false, id); 12809 } 12810 } catch (RemoteException ex) { 12811 } 12812 } 12813 }); 12814 } 12815 12816 /** 12817 * Check if the external storage media is available. This is true if there 12818 * is a mounted external storage medium or if the external storage is 12819 * emulated. 12820 */ 12821 private boolean isExternalMediaAvailable() { 12822 return mMediaMounted || Environment.isExternalStorageEmulated(); 12823 } 12824 12825 @Override 12826 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 12827 // writer 12828 synchronized (mPackages) { 12829 if (!isExternalMediaAvailable()) { 12830 // If the external storage is no longer mounted at this point, 12831 // the caller may not have been able to delete all of this 12832 // packages files and can not delete any more. Bail. 12833 return null; 12834 } 12835 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 12836 if (lastPackage != null) { 12837 pkgs.remove(lastPackage); 12838 } 12839 if (pkgs.size() > 0) { 12840 return pkgs.get(0); 12841 } 12842 } 12843 return null; 12844 } 12845 12846 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 12847 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 12848 userId, andCode ? 1 : 0, packageName); 12849 if (mSystemReady) { 12850 msg.sendToTarget(); 12851 } else { 12852 if (mPostSystemReadyMessages == null) { 12853 mPostSystemReadyMessages = new ArrayList<>(); 12854 } 12855 mPostSystemReadyMessages.add(msg); 12856 } 12857 } 12858 12859 void startCleaningPackages() { 12860 // reader 12861 if (!isExternalMediaAvailable()) { 12862 return; 12863 } 12864 synchronized (mPackages) { 12865 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 12866 return; 12867 } 12868 } 12869 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 12870 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 12871 IActivityManager am = ActivityManager.getService(); 12872 if (am != null) { 12873 try { 12874 am.startService(null, intent, null, -1, null, mContext.getOpPackageName(), 12875 UserHandle.USER_SYSTEM); 12876 } catch (RemoteException e) { 12877 } 12878 } 12879 } 12880 12881 @Override 12882 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 12883 int installFlags, String installerPackageName, int userId) { 12884 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 12885 12886 final int callingUid = Binder.getCallingUid(); 12887 enforceCrossUserPermission(callingUid, userId, 12888 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 12889 12890 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 12891 try { 12892 if (observer != null) { 12893 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 12894 } 12895 } catch (RemoteException re) { 12896 } 12897 return; 12898 } 12899 12900 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 12901 installFlags |= PackageManager.INSTALL_FROM_ADB; 12902 12903 } else { 12904 // Caller holds INSTALL_PACKAGES permission, so we're less strict 12905 // about installerPackageName. 12906 12907 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 12908 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 12909 } 12910 12911 UserHandle user; 12912 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 12913 user = UserHandle.ALL; 12914 } else { 12915 user = new UserHandle(userId); 12916 } 12917 12918 // Only system components can circumvent runtime permissions when installing. 12919 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 12920 && mContext.checkCallingOrSelfPermission(Manifest.permission 12921 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 12922 throw new SecurityException("You need the " 12923 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 12924 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 12925 } 12926 12927 final File originFile = new File(originPath); 12928 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 12929 12930 final Message msg = mHandler.obtainMessage(INIT_COPY); 12931 final VerificationInfo verificationInfo = new VerificationInfo( 12932 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 12933 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 12934 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 12935 null /*packageAbiOverride*/, null /*grantedPermissions*/, 12936 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN); 12937 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 12938 msg.obj = params; 12939 12940 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 12941 System.identityHashCode(msg.obj)); 12942 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 12943 System.identityHashCode(msg.obj)); 12944 12945 mHandler.sendMessage(msg); 12946 } 12947 12948 12949 /** 12950 * Ensure that the install reason matches what we know about the package installer (e.g. whether 12951 * it is acting on behalf on an enterprise or the user). 12952 * 12953 * Note that the ordering of the conditionals in this method is important. The checks we perform 12954 * are as follows, in this order: 12955 * 12956 * 1) If the install is being performed by a system app, we can trust the app to have set the 12957 * install reason correctly. Thus, we pass through the install reason unchanged, no matter 12958 * what it is. 12959 * 2) If the install is being performed by a device or profile owner app, the install reason 12960 * should be enterprise policy. However, we cannot be sure that the device or profile owner 12961 * set the install reason correctly. If the app targets an older SDK version where install 12962 * reasons did not exist yet, or if the app author simply forgot, the install reason may be 12963 * unset or wrong. Thus, we force the install reason to be enterprise policy. 12964 * 3) In all other cases, the install is being performed by a regular app that is neither part 12965 * of the system nor a device or profile owner. We have no reason to believe that this app is 12966 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was 12967 * set to enterprise policy and if so, change it to unknown instead. 12968 */ 12969 private int fixUpInstallReason(String installerPackageName, int installerUid, 12970 int installReason) { 12971 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid) 12972 == PERMISSION_GRANTED) { 12973 // If the install is being performed by a system app, we trust that app to have set the 12974 // install reason correctly. 12975 return installReason; 12976 } 12977 12978 final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 12979 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 12980 if (dpm != null) { 12981 ComponentName owner = null; 12982 try { 12983 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */); 12984 if (owner == null) { 12985 owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid)); 12986 } 12987 } catch (RemoteException e) { 12988 } 12989 if (owner != null && owner.getPackageName().equals(installerPackageName)) { 12990 // If the install is being performed by a device or profile owner, the install 12991 // reason should be enterprise policy. 12992 return PackageManager.INSTALL_REASON_POLICY; 12993 } 12994 } 12995 12996 if (installReason == PackageManager.INSTALL_REASON_POLICY) { 12997 // If the install is being performed by a regular app (i.e. neither system app nor 12998 // device or profile owner), we have no reason to believe that the app is acting on 12999 // behalf of an enterprise. If the app set the install reason to enterprise policy, 13000 // change it to unknown instead. 13001 return PackageManager.INSTALL_REASON_UNKNOWN; 13002 } 13003 13004 // If the install is being performed by a regular app and the install reason was set to any 13005 // value but enterprise policy, leave the install reason unchanged. 13006 return installReason; 13007 } 13008 13009 void installStage(String packageName, File stagedDir, String stagedCid, 13010 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 13011 String installerPackageName, int installerUid, UserHandle user, 13012 Certificate[][] certificates) { 13013 if (DEBUG_EPHEMERAL) { 13014 if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { 13015 Slog.d(TAG, "Ephemeral install of " + packageName); 13016 } 13017 } 13018 final VerificationInfo verificationInfo = new VerificationInfo( 13019 sessionParams.originatingUri, sessionParams.referrerUri, 13020 sessionParams.originatingUid, installerUid); 13021 13022 final OriginInfo origin; 13023 if (stagedDir != null) { 13024 origin = OriginInfo.fromStagedFile(stagedDir); 13025 } else { 13026 origin = OriginInfo.fromStagedContainer(stagedCid); 13027 } 13028 13029 final Message msg = mHandler.obtainMessage(INIT_COPY); 13030 final int installReason = fixUpInstallReason(installerPackageName, installerUid, 13031 sessionParams.installReason); 13032 final InstallParams params = new InstallParams(origin, null, observer, 13033 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 13034 verificationInfo, user, sessionParams.abiOverride, 13035 sessionParams.grantedRuntimePermissions, certificates, installReason); 13036 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 13037 msg.obj = params; 13038 13039 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 13040 System.identityHashCode(msg.obj)); 13041 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 13042 System.identityHashCode(msg.obj)); 13043 13044 mHandler.sendMessage(msg); 13045 } 13046 13047 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 13048 int userId) { 13049 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 13050 sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId); 13051 } 13052 13053 private void sendPackageAddedForNewUsers(String packageName, boolean isSystem, 13054 int appId, int... userIds) { 13055 if (ArrayUtils.isEmpty(userIds)) { 13056 return; 13057 } 13058 Bundle extras = new Bundle(1); 13059 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast 13060 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId)); 13061 13062 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 13063 packageName, extras, 0, null, null, userIds); 13064 if (isSystem) { 13065 mHandler.post(() -> { 13066 for (int userId : userIds) { 13067 sendBootCompletedBroadcastToSystemApp(packageName, userId); 13068 } 13069 } 13070 ); 13071 } 13072 } 13073 13074 /** 13075 * The just-installed/enabled app is bundled on the system, so presumed to be able to run 13076 * automatically without needing an explicit launch. 13077 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones. 13078 */ 13079 private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) { 13080 // If user is not running, the app didn't miss any broadcast 13081 if (!mUserManagerInternal.isUserRunning(userId)) { 13082 return; 13083 } 13084 final IActivityManager am = ActivityManager.getService(); 13085 try { 13086 // Deliver LOCKED_BOOT_COMPLETED first 13087 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED) 13088 .setPackage(packageName); 13089 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED}; 13090 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions, 13091 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 13092 13093 // Deliver BOOT_COMPLETED only if user is unlocked 13094 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) { 13095 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName); 13096 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions, 13097 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 13098 } 13099 } catch (RemoteException e) { 13100 throw e.rethrowFromSystemServer(); 13101 } 13102 } 13103 13104 @Override 13105 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 13106 int userId) { 13107 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13108 PackageSetting pkgSetting; 13109 final int uid = Binder.getCallingUid(); 13110 enforceCrossUserPermission(uid, userId, 13111 true /* requireFullPermission */, true /* checkShell */, 13112 "setApplicationHiddenSetting for user " + userId); 13113 13114 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 13115 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 13116 return false; 13117 } 13118 13119 long callingId = Binder.clearCallingIdentity(); 13120 try { 13121 boolean sendAdded = false; 13122 boolean sendRemoved = false; 13123 // writer 13124 synchronized (mPackages) { 13125 pkgSetting = mSettings.mPackages.get(packageName); 13126 if (pkgSetting == null) { 13127 return false; 13128 } 13129 // Do not allow "android" is being disabled 13130 if ("android".equals(packageName)) { 13131 Slog.w(TAG, "Cannot hide package: android"); 13132 return false; 13133 } 13134 // Cannot hide static shared libs as they are considered 13135 // a part of the using app (emulating static linking). Also 13136 // static libs are installed always on internal storage. 13137 PackageParser.Package pkg = mPackages.get(packageName); 13138 if (pkg != null && pkg.staticSharedLibName != null) { 13139 Slog.w(TAG, "Cannot hide package: " + packageName 13140 + " providing static shared library: " 13141 + pkg.staticSharedLibName); 13142 return false; 13143 } 13144 // Only allow protected packages to hide themselves. 13145 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 13146 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 13147 Slog.w(TAG, "Not hiding protected package: " + packageName); 13148 return false; 13149 } 13150 13151 if (pkgSetting.getHidden(userId) != hidden) { 13152 pkgSetting.setHidden(hidden, userId); 13153 mSettings.writePackageRestrictionsLPr(userId); 13154 if (hidden) { 13155 sendRemoved = true; 13156 } else { 13157 sendAdded = true; 13158 } 13159 } 13160 } 13161 if (sendAdded) { 13162 sendPackageAddedForUser(packageName, pkgSetting, userId); 13163 return true; 13164 } 13165 if (sendRemoved) { 13166 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 13167 "hiding pkg"); 13168 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 13169 return true; 13170 } 13171 } finally { 13172 Binder.restoreCallingIdentity(callingId); 13173 } 13174 return false; 13175 } 13176 13177 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 13178 int userId) { 13179 final PackageRemovedInfo info = new PackageRemovedInfo(); 13180 info.removedPackage = packageName; 13181 info.removedUsers = new int[] {userId}; 13182 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 13183 info.sendPackageRemovedBroadcasts(true /*killApp*/); 13184 } 13185 13186 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 13187 if (pkgList.length > 0) { 13188 Bundle extras = new Bundle(1); 13189 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 13190 13191 sendPackageBroadcast( 13192 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 13193 : Intent.ACTION_PACKAGES_UNSUSPENDED, 13194 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 13195 new int[] {userId}); 13196 } 13197 } 13198 13199 /** 13200 * Returns true if application is not found or there was an error. Otherwise it returns 13201 * the hidden state of the package for the given user. 13202 */ 13203 @Override 13204 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 13205 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13206 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13207 true /* requireFullPermission */, false /* checkShell */, 13208 "getApplicationHidden for user " + userId); 13209 PackageSetting pkgSetting; 13210 long callingId = Binder.clearCallingIdentity(); 13211 try { 13212 // writer 13213 synchronized (mPackages) { 13214 pkgSetting = mSettings.mPackages.get(packageName); 13215 if (pkgSetting == null) { 13216 return true; 13217 } 13218 return pkgSetting.getHidden(userId); 13219 } 13220 } finally { 13221 Binder.restoreCallingIdentity(callingId); 13222 } 13223 } 13224 13225 /** 13226 * @hide 13227 */ 13228 @Override 13229 public int installExistingPackageAsUser(String packageName, int userId, int installFlags, 13230 int installReason) { 13231 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 13232 null); 13233 PackageSetting pkgSetting; 13234 final int uid = Binder.getCallingUid(); 13235 enforceCrossUserPermission(uid, userId, 13236 true /* requireFullPermission */, true /* checkShell */, 13237 "installExistingPackage for user " + userId); 13238 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 13239 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 13240 } 13241 13242 long callingId = Binder.clearCallingIdentity(); 13243 try { 13244 boolean installed = false; 13245 final boolean instantApp = 13246 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 13247 final boolean fullApp = 13248 (installFlags & PackageManager.INSTALL_FULL_APP) != 0; 13249 13250 // writer 13251 synchronized (mPackages) { 13252 pkgSetting = mSettings.mPackages.get(packageName); 13253 if (pkgSetting == null) { 13254 return PackageManager.INSTALL_FAILED_INVALID_URI; 13255 } 13256 if (!pkgSetting.getInstalled(userId)) { 13257 pkgSetting.setInstalled(true, userId); 13258 pkgSetting.setHidden(false, userId); 13259 pkgSetting.setInstallReason(installReason, userId); 13260 mSettings.writePackageRestrictionsLPr(userId); 13261 installed = true; 13262 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 13263 // upgrade app from instant to full; we don't allow app downgrade 13264 installed = true; 13265 } 13266 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp); 13267 } 13268 13269 if (installed) { 13270 if (pkgSetting.pkg != null) { 13271 synchronized (mInstallLock) { 13272 // We don't need to freeze for a brand new install 13273 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 13274 } 13275 } 13276 sendPackageAddedForUser(packageName, pkgSetting, userId); 13277 } 13278 } finally { 13279 Binder.restoreCallingIdentity(callingId); 13280 } 13281 13282 return PackageManager.INSTALL_SUCCEEDED; 13283 } 13284 13285 void setInstantAppForUser(PackageSetting pkgSetting, int userId, 13286 boolean instantApp, boolean fullApp) { 13287 // no state specified; do nothing 13288 if (!instantApp && !fullApp) { 13289 return; 13290 } 13291 if (userId != UserHandle.USER_ALL) { 13292 if (instantApp && !pkgSetting.getInstantApp(userId)) { 13293 pkgSetting.setInstantApp(true /*instantApp*/, userId); 13294 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 13295 pkgSetting.setInstantApp(false /*instantApp*/, userId); 13296 } 13297 } else { 13298 for (int currentUserId : sUserManager.getUserIds()) { 13299 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) { 13300 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId); 13301 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) { 13302 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId); 13303 } 13304 } 13305 } 13306 } 13307 13308 boolean isUserRestricted(int userId, String restrictionKey) { 13309 Bundle restrictions = sUserManager.getUserRestrictions(userId); 13310 if (restrictions.getBoolean(restrictionKey, false)) { 13311 Log.w(TAG, "User is restricted: " + restrictionKey); 13312 return true; 13313 } 13314 return false; 13315 } 13316 13317 @Override 13318 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 13319 int userId) { 13320 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13321 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13322 true /* requireFullPermission */, true /* checkShell */, 13323 "setPackagesSuspended for user " + userId); 13324 13325 if (ArrayUtils.isEmpty(packageNames)) { 13326 return packageNames; 13327 } 13328 13329 // List of package names for whom the suspended state has changed. 13330 List<String> changedPackages = new ArrayList<>(packageNames.length); 13331 // List of package names for whom the suspended state is not set as requested in this 13332 // method. 13333 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 13334 long callingId = Binder.clearCallingIdentity(); 13335 try { 13336 for (int i = 0; i < packageNames.length; i++) { 13337 String packageName = packageNames[i]; 13338 boolean changed = false; 13339 final int appId; 13340 synchronized (mPackages) { 13341 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 13342 if (pkgSetting == null) { 13343 Slog.w(TAG, "Could not find package setting for package \"" + packageName 13344 + "\". Skipping suspending/un-suspending."); 13345 unactionedPackages.add(packageName); 13346 continue; 13347 } 13348 appId = pkgSetting.appId; 13349 if (pkgSetting.getSuspended(userId) != suspended) { 13350 if (!canSuspendPackageForUserLocked(packageName, userId)) { 13351 unactionedPackages.add(packageName); 13352 continue; 13353 } 13354 pkgSetting.setSuspended(suspended, userId); 13355 mSettings.writePackageRestrictionsLPr(userId); 13356 changed = true; 13357 changedPackages.add(packageName); 13358 } 13359 } 13360 13361 if (changed && suspended) { 13362 killApplication(packageName, UserHandle.getUid(userId, appId), 13363 "suspending package"); 13364 } 13365 } 13366 } finally { 13367 Binder.restoreCallingIdentity(callingId); 13368 } 13369 13370 if (!changedPackages.isEmpty()) { 13371 sendPackagesSuspendedForUser(changedPackages.toArray( 13372 new String[changedPackages.size()]), userId, suspended); 13373 } 13374 13375 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 13376 } 13377 13378 @Override 13379 public boolean isPackageSuspendedForUser(String packageName, int userId) { 13380 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13381 true /* requireFullPermission */, false /* checkShell */, 13382 "isPackageSuspendedForUser for user " + userId); 13383 synchronized (mPackages) { 13384 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 13385 if (pkgSetting == null) { 13386 throw new IllegalArgumentException("Unknown target package: " + packageName); 13387 } 13388 return pkgSetting.getSuspended(userId); 13389 } 13390 } 13391 13392 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 13393 if (isPackageDeviceAdmin(packageName, userId)) { 13394 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13395 + "\": has an active device admin"); 13396 return false; 13397 } 13398 13399 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 13400 if (packageName.equals(activeLauncherPackageName)) { 13401 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13402 + "\": contains the active launcher"); 13403 return false; 13404 } 13405 13406 if (packageName.equals(mRequiredInstallerPackage)) { 13407 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13408 + "\": required for package installation"); 13409 return false; 13410 } 13411 13412 if (packageName.equals(mRequiredUninstallerPackage)) { 13413 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13414 + "\": required for package uninstallation"); 13415 return false; 13416 } 13417 13418 if (packageName.equals(mRequiredVerifierPackage)) { 13419 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13420 + "\": required for package verification"); 13421 return false; 13422 } 13423 13424 if (packageName.equals(getDefaultDialerPackageName(userId))) { 13425 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13426 + "\": is the default dialer"); 13427 return false; 13428 } 13429 13430 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 13431 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13432 + "\": protected package"); 13433 return false; 13434 } 13435 13436 // Cannot suspend static shared libs as they are considered 13437 // a part of the using app (emulating static linking). Also 13438 // static libs are installed always on internal storage. 13439 PackageParser.Package pkg = mPackages.get(packageName); 13440 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) { 13441 Slog.w(TAG, "Cannot suspend package: " + packageName 13442 + " providing static shared library: " 13443 + pkg.staticSharedLibName); 13444 return false; 13445 } 13446 13447 return true; 13448 } 13449 13450 private String getActiveLauncherPackageName(int userId) { 13451 Intent intent = new Intent(Intent.ACTION_MAIN); 13452 intent.addCategory(Intent.CATEGORY_HOME); 13453 ResolveInfo resolveInfo = resolveIntent( 13454 intent, 13455 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 13456 PackageManager.MATCH_DEFAULT_ONLY, 13457 userId); 13458 13459 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 13460 } 13461 13462 private String getDefaultDialerPackageName(int userId) { 13463 synchronized (mPackages) { 13464 return mSettings.getDefaultDialerPackageNameLPw(userId); 13465 } 13466 } 13467 13468 @Override 13469 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 13470 mContext.enforceCallingOrSelfPermission( 13471 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13472 "Only package verification agents can verify applications"); 13473 13474 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 13475 final PackageVerificationResponse response = new PackageVerificationResponse( 13476 verificationCode, Binder.getCallingUid()); 13477 msg.arg1 = id; 13478 msg.obj = response; 13479 mHandler.sendMessage(msg); 13480 } 13481 13482 @Override 13483 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 13484 long millisecondsToDelay) { 13485 mContext.enforceCallingOrSelfPermission( 13486 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13487 "Only package verification agents can extend verification timeouts"); 13488 13489 final PackageVerificationState state = mPendingVerification.get(id); 13490 final PackageVerificationResponse response = new PackageVerificationResponse( 13491 verificationCodeAtTimeout, Binder.getCallingUid()); 13492 13493 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 13494 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 13495 } 13496 if (millisecondsToDelay < 0) { 13497 millisecondsToDelay = 0; 13498 } 13499 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 13500 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 13501 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 13502 } 13503 13504 if ((state != null) && !state.timeoutExtended()) { 13505 state.extendTimeout(); 13506 13507 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 13508 msg.arg1 = id; 13509 msg.obj = response; 13510 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 13511 } 13512 } 13513 13514 private void broadcastPackageVerified(int verificationId, Uri packageUri, 13515 int verificationCode, UserHandle user) { 13516 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 13517 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 13518 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 13519 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 13520 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 13521 13522 mContext.sendBroadcastAsUser(intent, user, 13523 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 13524 } 13525 13526 private ComponentName matchComponentForVerifier(String packageName, 13527 List<ResolveInfo> receivers) { 13528 ActivityInfo targetReceiver = null; 13529 13530 final int NR = receivers.size(); 13531 for (int i = 0; i < NR; i++) { 13532 final ResolveInfo info = receivers.get(i); 13533 if (info.activityInfo == null) { 13534 continue; 13535 } 13536 13537 if (packageName.equals(info.activityInfo.packageName)) { 13538 targetReceiver = info.activityInfo; 13539 break; 13540 } 13541 } 13542 13543 if (targetReceiver == null) { 13544 return null; 13545 } 13546 13547 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 13548 } 13549 13550 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 13551 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 13552 if (pkgInfo.verifiers.length == 0) { 13553 return null; 13554 } 13555 13556 final int N = pkgInfo.verifiers.length; 13557 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 13558 for (int i = 0; i < N; i++) { 13559 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 13560 13561 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 13562 receivers); 13563 if (comp == null) { 13564 continue; 13565 } 13566 13567 final int verifierUid = getUidForVerifier(verifierInfo); 13568 if (verifierUid == -1) { 13569 continue; 13570 } 13571 13572 if (DEBUG_VERIFY) { 13573 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 13574 + " with the correct signature"); 13575 } 13576 sufficientVerifiers.add(comp); 13577 verificationState.addSufficientVerifier(verifierUid); 13578 } 13579 13580 return sufficientVerifiers; 13581 } 13582 13583 private int getUidForVerifier(VerifierInfo verifierInfo) { 13584 synchronized (mPackages) { 13585 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 13586 if (pkg == null) { 13587 return -1; 13588 } else if (pkg.mSignatures.length != 1) { 13589 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 13590 + " has more than one signature; ignoring"); 13591 return -1; 13592 } 13593 13594 /* 13595 * If the public key of the package's signature does not match 13596 * our expected public key, then this is a different package and 13597 * we should skip. 13598 */ 13599 13600 final byte[] expectedPublicKey; 13601 try { 13602 final Signature verifierSig = pkg.mSignatures[0]; 13603 final PublicKey publicKey = verifierSig.getPublicKey(); 13604 expectedPublicKey = publicKey.getEncoded(); 13605 } catch (CertificateException e) { 13606 return -1; 13607 } 13608 13609 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 13610 13611 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 13612 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 13613 + " does not have the expected public key; ignoring"); 13614 return -1; 13615 } 13616 13617 return pkg.applicationInfo.uid; 13618 } 13619 } 13620 13621 @Override 13622 public void finishPackageInstall(int token, boolean didLaunch) { 13623 enforceSystemOrRoot("Only the system is allowed to finish installs"); 13624 13625 if (DEBUG_INSTALL) { 13626 Slog.v(TAG, "BM finishing package install for " + token); 13627 } 13628 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 13629 13630 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 13631 mHandler.sendMessage(msg); 13632 } 13633 13634 /** 13635 * Get the verification agent timeout. 13636 * 13637 * @return verification timeout in milliseconds 13638 */ 13639 private long getVerificationTimeout() { 13640 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 13641 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 13642 DEFAULT_VERIFICATION_TIMEOUT); 13643 } 13644 13645 /** 13646 * Get the default verification agent response code. 13647 * 13648 * @return default verification response code 13649 */ 13650 private int getDefaultVerificationResponse() { 13651 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13652 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 13653 DEFAULT_VERIFICATION_RESPONSE); 13654 } 13655 13656 /** 13657 * Check whether or not package verification has been enabled. 13658 * 13659 * @return true if verification should be performed 13660 */ 13661 private boolean isVerificationEnabled(int userId, int installFlags) { 13662 if (!DEFAULT_VERIFY_ENABLE) { 13663 return false; 13664 } 13665 // Ephemeral apps don't get the full verification treatment 13666 if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { 13667 if (DEBUG_EPHEMERAL) { 13668 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 13669 } 13670 return false; 13671 } 13672 13673 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 13674 13675 // Check if installing from ADB 13676 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 13677 // Do not run verification in a test harness environment 13678 if (ActivityManager.isRunningInTestHarness()) { 13679 return false; 13680 } 13681 if (ensureVerifyAppsEnabled) { 13682 return true; 13683 } 13684 // Check if the developer does not want package verification for ADB installs 13685 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13686 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 13687 return false; 13688 } 13689 } 13690 13691 if (ensureVerifyAppsEnabled) { 13692 return true; 13693 } 13694 13695 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13696 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 13697 } 13698 13699 @Override 13700 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 13701 throws RemoteException { 13702 mContext.enforceCallingOrSelfPermission( 13703 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 13704 "Only intentfilter verification agents can verify applications"); 13705 13706 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 13707 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 13708 Binder.getCallingUid(), verificationCode, failedDomains); 13709 msg.arg1 = id; 13710 msg.obj = response; 13711 mHandler.sendMessage(msg); 13712 } 13713 13714 @Override 13715 public int getIntentVerificationStatus(String packageName, int userId) { 13716 synchronized (mPackages) { 13717 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 13718 } 13719 } 13720 13721 @Override 13722 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 13723 mContext.enforceCallingOrSelfPermission( 13724 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13725 13726 boolean result = false; 13727 synchronized (mPackages) { 13728 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 13729 } 13730 if (result) { 13731 scheduleWritePackageRestrictionsLocked(userId); 13732 } 13733 return result; 13734 } 13735 13736 @Override 13737 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 13738 String packageName) { 13739 synchronized (mPackages) { 13740 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 13741 } 13742 } 13743 13744 @Override 13745 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 13746 if (TextUtils.isEmpty(packageName)) { 13747 return ParceledListSlice.emptyList(); 13748 } 13749 synchronized (mPackages) { 13750 PackageParser.Package pkg = mPackages.get(packageName); 13751 if (pkg == null || pkg.activities == null) { 13752 return ParceledListSlice.emptyList(); 13753 } 13754 final int count = pkg.activities.size(); 13755 ArrayList<IntentFilter> result = new ArrayList<>(); 13756 for (int n=0; n<count; n++) { 13757 PackageParser.Activity activity = pkg.activities.get(n); 13758 if (activity.intents != null && activity.intents.size() > 0) { 13759 result.addAll(activity.intents); 13760 } 13761 } 13762 return new ParceledListSlice<>(result); 13763 } 13764 } 13765 13766 @Override 13767 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 13768 mContext.enforceCallingOrSelfPermission( 13769 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13770 13771 synchronized (mPackages) { 13772 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 13773 if (packageName != null) { 13774 result |= updateIntentVerificationStatus(packageName, 13775 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 13776 userId); 13777 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 13778 packageName, userId); 13779 } 13780 return result; 13781 } 13782 } 13783 13784 @Override 13785 public String getDefaultBrowserPackageName(int userId) { 13786 synchronized (mPackages) { 13787 return mSettings.getDefaultBrowserPackageNameLPw(userId); 13788 } 13789 } 13790 13791 /** 13792 * Get the "allow unknown sources" setting. 13793 * 13794 * @return the current "allow unknown sources" setting 13795 */ 13796 private int getUnknownSourcesSettings() { 13797 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 13798 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 13799 -1); 13800 } 13801 13802 @Override 13803 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 13804 final int uid = Binder.getCallingUid(); 13805 // writer 13806 synchronized (mPackages) { 13807 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 13808 if (targetPackageSetting == null) { 13809 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 13810 } 13811 13812 PackageSetting installerPackageSetting; 13813 if (installerPackageName != null) { 13814 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 13815 if (installerPackageSetting == null) { 13816 throw new IllegalArgumentException("Unknown installer package: " 13817 + installerPackageName); 13818 } 13819 } else { 13820 installerPackageSetting = null; 13821 } 13822 13823 Signature[] callerSignature; 13824 Object obj = mSettings.getUserIdLPr(uid); 13825 if (obj != null) { 13826 if (obj instanceof SharedUserSetting) { 13827 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 13828 } else if (obj instanceof PackageSetting) { 13829 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 13830 } else { 13831 throw new SecurityException("Bad object " + obj + " for uid " + uid); 13832 } 13833 } else { 13834 throw new SecurityException("Unknown calling UID: " + uid); 13835 } 13836 13837 // Verify: can't set installerPackageName to a package that is 13838 // not signed with the same cert as the caller. 13839 if (installerPackageSetting != null) { 13840 if (compareSignatures(callerSignature, 13841 installerPackageSetting.signatures.mSignatures) 13842 != PackageManager.SIGNATURE_MATCH) { 13843 throw new SecurityException( 13844 "Caller does not have same cert as new installer package " 13845 + installerPackageName); 13846 } 13847 } 13848 13849 // Verify: if target already has an installer package, it must 13850 // be signed with the same cert as the caller. 13851 if (targetPackageSetting.installerPackageName != null) { 13852 PackageSetting setting = mSettings.mPackages.get( 13853 targetPackageSetting.installerPackageName); 13854 // If the currently set package isn't valid, then it's always 13855 // okay to change it. 13856 if (setting != null) { 13857 if (compareSignatures(callerSignature, 13858 setting.signatures.mSignatures) 13859 != PackageManager.SIGNATURE_MATCH) { 13860 throw new SecurityException( 13861 "Caller does not have same cert as old installer package " 13862 + targetPackageSetting.installerPackageName); 13863 } 13864 } 13865 } 13866 13867 // Okay! 13868 targetPackageSetting.installerPackageName = installerPackageName; 13869 if (installerPackageName != null) { 13870 mSettings.mInstallerPackages.add(installerPackageName); 13871 } 13872 scheduleWriteSettingsLocked(); 13873 } 13874 } 13875 13876 @Override 13877 public void setApplicationCategoryHint(String packageName, int categoryHint, 13878 String callerPackageName) { 13879 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), 13880 callerPackageName); 13881 synchronized (mPackages) { 13882 PackageSetting ps = mSettings.mPackages.get(packageName); 13883 if (ps == null) { 13884 throw new IllegalArgumentException("Unknown target package " + packageName); 13885 } 13886 13887 if (!Objects.equals(callerPackageName, ps.installerPackageName)) { 13888 throw new IllegalArgumentException("Calling package " + callerPackageName 13889 + " is not installer for " + packageName); 13890 } 13891 13892 if (ps.categoryHint != categoryHint) { 13893 ps.categoryHint = categoryHint; 13894 scheduleWriteSettingsLocked(); 13895 } 13896 } 13897 } 13898 13899 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 13900 // Queue up an async operation since the package installation may take a little while. 13901 mHandler.post(new Runnable() { 13902 public void run() { 13903 mHandler.removeCallbacks(this); 13904 // Result object to be returned 13905 PackageInstalledInfo res = new PackageInstalledInfo(); 13906 res.setReturnCode(currentStatus); 13907 res.uid = -1; 13908 res.pkg = null; 13909 res.removedInfo = null; 13910 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13911 args.doPreInstall(res.returnCode); 13912 synchronized (mInstallLock) { 13913 installPackageTracedLI(args, res); 13914 } 13915 args.doPostInstall(res.returnCode, res.uid); 13916 } 13917 13918 // A restore should be performed at this point if (a) the install 13919 // succeeded, (b) the operation is not an update, and (c) the new 13920 // package has not opted out of backup participation. 13921 final boolean update = res.removedInfo != null 13922 && res.removedInfo.removedPackage != null; 13923 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 13924 boolean doRestore = !update 13925 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 13926 13927 // Set up the post-install work request bookkeeping. This will be used 13928 // and cleaned up by the post-install event handling regardless of whether 13929 // there's a restore pass performed. Token values are >= 1. 13930 int token; 13931 if (mNextInstallToken < 0) mNextInstallToken = 1; 13932 token = mNextInstallToken++; 13933 13934 PostInstallData data = new PostInstallData(args, res); 13935 mRunningInstalls.put(token, data); 13936 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 13937 13938 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 13939 // Pass responsibility to the Backup Manager. It will perform a 13940 // restore if appropriate, then pass responsibility back to the 13941 // Package Manager to run the post-install observer callbacks 13942 // and broadcasts. 13943 IBackupManager bm = IBackupManager.Stub.asInterface( 13944 ServiceManager.getService(Context.BACKUP_SERVICE)); 13945 if (bm != null) { 13946 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 13947 + " to BM for possible restore"); 13948 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 13949 try { 13950 // TODO: http://b/22388012 13951 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 13952 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 13953 } else { 13954 doRestore = false; 13955 } 13956 } catch (RemoteException e) { 13957 // can't happen; the backup manager is local 13958 } catch (Exception e) { 13959 Slog.e(TAG, "Exception trying to enqueue restore", e); 13960 doRestore = false; 13961 } 13962 } else { 13963 Slog.e(TAG, "Backup Manager not found!"); 13964 doRestore = false; 13965 } 13966 } 13967 13968 if (!doRestore) { 13969 // No restore possible, or the Backup Manager was mysteriously not 13970 // available -- just fire the post-install work request directly. 13971 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 13972 13973 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 13974 13975 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 13976 mHandler.sendMessage(msg); 13977 } 13978 } 13979 }); 13980 } 13981 13982 /** 13983 * Callback from PackageSettings whenever an app is first transitioned out of the 13984 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 13985 * the app was "launched" for a restoreAtInstall operation. Therefore we check 13986 * here whether the app is the target of an ongoing install, and only send the 13987 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 13988 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 13989 * handling. 13990 */ 13991 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 13992 // Serialize this with the rest of the install-process message chain. In the 13993 // restore-at-install case, this Runnable will necessarily run before the 13994 // POST_INSTALL message is processed, so the contents of mRunningInstalls 13995 // are coherent. In the non-restore case, the app has already completed install 13996 // and been launched through some other means, so it is not in a problematic 13997 // state for observers to see the FIRST_LAUNCH signal. 13998 mHandler.post(new Runnable() { 13999 @Override 14000 public void run() { 14001 for (int i = 0; i < mRunningInstalls.size(); i++) { 14002 final PostInstallData data = mRunningInstalls.valueAt(i); 14003 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14004 continue; 14005 } 14006 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 14007 // right package; but is it for the right user? 14008 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 14009 if (userId == data.res.newUsers[uIndex]) { 14010 if (DEBUG_BACKUP) { 14011 Slog.i(TAG, "Package " + pkgName 14012 + " being restored so deferring FIRST_LAUNCH"); 14013 } 14014 return; 14015 } 14016 } 14017 } 14018 } 14019 // didn't find it, so not being restored 14020 if (DEBUG_BACKUP) { 14021 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 14022 } 14023 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 14024 } 14025 }); 14026 } 14027 14028 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 14029 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 14030 installerPkg, null, userIds); 14031 } 14032 14033 private abstract class HandlerParams { 14034 private static final int MAX_RETRIES = 4; 14035 14036 /** 14037 * Number of times startCopy() has been attempted and had a non-fatal 14038 * error. 14039 */ 14040 private int mRetries = 0; 14041 14042 /** User handle for the user requesting the information or installation. */ 14043 private final UserHandle mUser; 14044 String traceMethod; 14045 int traceCookie; 14046 14047 HandlerParams(UserHandle user) { 14048 mUser = user; 14049 } 14050 14051 UserHandle getUser() { 14052 return mUser; 14053 } 14054 14055 HandlerParams setTraceMethod(String traceMethod) { 14056 this.traceMethod = traceMethod; 14057 return this; 14058 } 14059 14060 HandlerParams setTraceCookie(int traceCookie) { 14061 this.traceCookie = traceCookie; 14062 return this; 14063 } 14064 14065 final boolean startCopy() { 14066 boolean res; 14067 try { 14068 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 14069 14070 if (++mRetries > MAX_RETRIES) { 14071 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 14072 mHandler.sendEmptyMessage(MCS_GIVE_UP); 14073 handleServiceError(); 14074 return false; 14075 } else { 14076 handleStartCopy(); 14077 res = true; 14078 } 14079 } catch (RemoteException e) { 14080 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 14081 mHandler.sendEmptyMessage(MCS_RECONNECT); 14082 res = false; 14083 } 14084 handleReturnCode(); 14085 return res; 14086 } 14087 14088 final void serviceError() { 14089 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 14090 handleServiceError(); 14091 handleReturnCode(); 14092 } 14093 14094 abstract void handleStartCopy() throws RemoteException; 14095 abstract void handleServiceError(); 14096 abstract void handleReturnCode(); 14097 } 14098 14099 class MeasureParams extends HandlerParams { 14100 private final PackageStats mStats; 14101 private boolean mSuccess; 14102 14103 private final IPackageStatsObserver mObserver; 14104 14105 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 14106 super(new UserHandle(stats.userHandle)); 14107 mObserver = observer; 14108 mStats = stats; 14109 } 14110 14111 @Override 14112 public String toString() { 14113 return "MeasureParams{" 14114 + Integer.toHexString(System.identityHashCode(this)) 14115 + " " + mStats.packageName + "}"; 14116 } 14117 14118 @Override 14119 void handleStartCopy() throws RemoteException { 14120 synchronized (mInstallLock) { 14121 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 14122 } 14123 14124 if (mSuccess) { 14125 boolean mounted = false; 14126 try { 14127 final String status = Environment.getExternalStorageState(); 14128 mounted = (Environment.MEDIA_MOUNTED.equals(status) 14129 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 14130 } catch (Exception e) { 14131 } 14132 14133 if (mounted) { 14134 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 14135 14136 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 14137 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 14138 14139 mStats.externalDataSize = calculateDirectorySize(mContainerService, 14140 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 14141 14142 // Always subtract cache size, since it's a subdirectory 14143 mStats.externalDataSize -= mStats.externalCacheSize; 14144 14145 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 14146 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 14147 14148 mStats.externalObbSize = calculateDirectorySize(mContainerService, 14149 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 14150 } 14151 } 14152 } 14153 14154 @Override 14155 void handleReturnCode() { 14156 if (mObserver != null) { 14157 try { 14158 mObserver.onGetStatsCompleted(mStats, mSuccess); 14159 } catch (RemoteException e) { 14160 Slog.i(TAG, "Observer no longer exists."); 14161 } 14162 } 14163 } 14164 14165 @Override 14166 void handleServiceError() { 14167 Slog.e(TAG, "Could not measure application " + mStats.packageName 14168 + " external storage"); 14169 } 14170 } 14171 14172 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 14173 throws RemoteException { 14174 long result = 0; 14175 for (File path : paths) { 14176 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 14177 } 14178 return result; 14179 } 14180 14181 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 14182 for (File path : paths) { 14183 try { 14184 mcs.clearDirectory(path.getAbsolutePath()); 14185 } catch (RemoteException e) { 14186 } 14187 } 14188 } 14189 14190 static class OriginInfo { 14191 /** 14192 * Location where install is coming from, before it has been 14193 * copied/renamed into place. This could be a single monolithic APK 14194 * file, or a cluster directory. This location may be untrusted. 14195 */ 14196 final File file; 14197 final String cid; 14198 14199 /** 14200 * Flag indicating that {@link #file} or {@link #cid} has already been 14201 * staged, meaning downstream users don't need to defensively copy the 14202 * contents. 14203 */ 14204 final boolean staged; 14205 14206 /** 14207 * Flag indicating that {@link #file} or {@link #cid} is an already 14208 * installed app that is being moved. 14209 */ 14210 final boolean existing; 14211 14212 final String resolvedPath; 14213 final File resolvedFile; 14214 14215 static OriginInfo fromNothing() { 14216 return new OriginInfo(null, null, false, false); 14217 } 14218 14219 static OriginInfo fromUntrustedFile(File file) { 14220 return new OriginInfo(file, null, false, false); 14221 } 14222 14223 static OriginInfo fromExistingFile(File file) { 14224 return new OriginInfo(file, null, false, true); 14225 } 14226 14227 static OriginInfo fromStagedFile(File file) { 14228 return new OriginInfo(file, null, true, false); 14229 } 14230 14231 static OriginInfo fromStagedContainer(String cid) { 14232 return new OriginInfo(null, cid, true, false); 14233 } 14234 14235 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 14236 this.file = file; 14237 this.cid = cid; 14238 this.staged = staged; 14239 this.existing = existing; 14240 14241 if (cid != null) { 14242 resolvedPath = PackageHelper.getSdDir(cid); 14243 resolvedFile = new File(resolvedPath); 14244 } else if (file != null) { 14245 resolvedPath = file.getAbsolutePath(); 14246 resolvedFile = file; 14247 } else { 14248 resolvedPath = null; 14249 resolvedFile = null; 14250 } 14251 } 14252 } 14253 14254 static class MoveInfo { 14255 final int moveId; 14256 final String fromUuid; 14257 final String toUuid; 14258 final String packageName; 14259 final String dataAppName; 14260 final int appId; 14261 final String seinfo; 14262 final int targetSdkVersion; 14263 14264 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 14265 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 14266 this.moveId = moveId; 14267 this.fromUuid = fromUuid; 14268 this.toUuid = toUuid; 14269 this.packageName = packageName; 14270 this.dataAppName = dataAppName; 14271 this.appId = appId; 14272 this.seinfo = seinfo; 14273 this.targetSdkVersion = targetSdkVersion; 14274 } 14275 } 14276 14277 static class VerificationInfo { 14278 /** A constant used to indicate that a uid value is not present. */ 14279 public static final int NO_UID = -1; 14280 14281 /** URI referencing where the package was downloaded from. */ 14282 final Uri originatingUri; 14283 14284 /** HTTP referrer URI associated with the originatingURI. */ 14285 final Uri referrer; 14286 14287 /** UID of the application that the install request originated from. */ 14288 final int originatingUid; 14289 14290 /** UID of application requesting the install */ 14291 final int installerUid; 14292 14293 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 14294 this.originatingUri = originatingUri; 14295 this.referrer = referrer; 14296 this.originatingUid = originatingUid; 14297 this.installerUid = installerUid; 14298 } 14299 } 14300 14301 class InstallParams extends HandlerParams { 14302 final OriginInfo origin; 14303 final MoveInfo move; 14304 final IPackageInstallObserver2 observer; 14305 int installFlags; 14306 final String installerPackageName; 14307 final String volumeUuid; 14308 private InstallArgs mArgs; 14309 private int mRet; 14310 final String packageAbiOverride; 14311 final String[] grantedRuntimePermissions; 14312 final VerificationInfo verificationInfo; 14313 final Certificate[][] certificates; 14314 final int installReason; 14315 14316 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 14317 int installFlags, String installerPackageName, String volumeUuid, 14318 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 14319 String[] grantedPermissions, Certificate[][] certificates, int installReason) { 14320 super(user); 14321 this.origin = origin; 14322 this.move = move; 14323 this.observer = observer; 14324 this.installFlags = installFlags; 14325 this.installerPackageName = installerPackageName; 14326 this.volumeUuid = volumeUuid; 14327 this.verificationInfo = verificationInfo; 14328 this.packageAbiOverride = packageAbiOverride; 14329 this.grantedRuntimePermissions = grantedPermissions; 14330 this.certificates = certificates; 14331 this.installReason = installReason; 14332 } 14333 14334 @Override 14335 public String toString() { 14336 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 14337 + " file=" + origin.file + " cid=" + origin.cid + "}"; 14338 } 14339 14340 private int installLocationPolicy(PackageInfoLite pkgLite) { 14341 String packageName = pkgLite.packageName; 14342 int installLocation = pkgLite.installLocation; 14343 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14344 // reader 14345 synchronized (mPackages) { 14346 // Currently installed package which the new package is attempting to replace or 14347 // null if no such package is installed. 14348 PackageParser.Package installedPkg = mPackages.get(packageName); 14349 // Package which currently owns the data which the new package will own if installed. 14350 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 14351 // will be null whereas dataOwnerPkg will contain information about the package 14352 // which was uninstalled while keeping its data. 14353 PackageParser.Package dataOwnerPkg = installedPkg; 14354 if (dataOwnerPkg == null) { 14355 PackageSetting ps = mSettings.mPackages.get(packageName); 14356 if (ps != null) { 14357 dataOwnerPkg = ps.pkg; 14358 } 14359 } 14360 14361 if (dataOwnerPkg != null) { 14362 // If installed, the package will get access to data left on the device by its 14363 // predecessor. As a security measure, this is permited only if this is not a 14364 // version downgrade or if the predecessor package is marked as debuggable and 14365 // a downgrade is explicitly requested. 14366 // 14367 // On debuggable platform builds, downgrades are permitted even for 14368 // non-debuggable packages to make testing easier. Debuggable platform builds do 14369 // not offer security guarantees and thus it's OK to disable some security 14370 // mechanisms to make debugging/testing easier on those builds. However, even on 14371 // debuggable builds downgrades of packages are permitted only if requested via 14372 // installFlags. This is because we aim to keep the behavior of debuggable 14373 // platform builds as close as possible to the behavior of non-debuggable 14374 // platform builds. 14375 final boolean downgradeRequested = 14376 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 14377 final boolean packageDebuggable = 14378 (dataOwnerPkg.applicationInfo.flags 14379 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 14380 final boolean downgradePermitted = 14381 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 14382 if (!downgradePermitted) { 14383 try { 14384 checkDowngrade(dataOwnerPkg, pkgLite); 14385 } catch (PackageManagerException e) { 14386 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 14387 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 14388 } 14389 } 14390 } 14391 14392 if (installedPkg != null) { 14393 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 14394 // Check for updated system application. 14395 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14396 if (onSd) { 14397 Slog.w(TAG, "Cannot install update to system app on sdcard"); 14398 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 14399 } 14400 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14401 } else { 14402 if (onSd) { 14403 // Install flag overrides everything. 14404 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14405 } 14406 // If current upgrade specifies particular preference 14407 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 14408 // Application explicitly specified internal. 14409 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14410 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 14411 // App explictly prefers external. Let policy decide 14412 } else { 14413 // Prefer previous location 14414 if (isExternal(installedPkg)) { 14415 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14416 } 14417 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14418 } 14419 } 14420 } else { 14421 // Invalid install. Return error code 14422 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 14423 } 14424 } 14425 } 14426 // All the special cases have been taken care of. 14427 // Return result based on recommended install location. 14428 if (onSd) { 14429 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14430 } 14431 return pkgLite.recommendedInstallLocation; 14432 } 14433 14434 /* 14435 * Invoke remote method to get package information and install 14436 * location values. Override install location based on default 14437 * policy if needed and then create install arguments based 14438 * on the install location. 14439 */ 14440 public void handleStartCopy() throws RemoteException { 14441 int ret = PackageManager.INSTALL_SUCCEEDED; 14442 14443 // If we're already staged, we've firmly committed to an install location 14444 if (origin.staged) { 14445 if (origin.file != null) { 14446 installFlags |= PackageManager.INSTALL_INTERNAL; 14447 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 14448 } else if (origin.cid != null) { 14449 installFlags |= PackageManager.INSTALL_EXTERNAL; 14450 installFlags &= ~PackageManager.INSTALL_INTERNAL; 14451 } else { 14452 throw new IllegalStateException("Invalid stage location"); 14453 } 14454 } 14455 14456 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14457 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 14458 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14459 PackageInfoLite pkgLite = null; 14460 14461 if (onInt && onSd) { 14462 // Check if both bits are set. 14463 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 14464 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14465 } else if (onSd && ephemeral) { 14466 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 14467 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14468 } else { 14469 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 14470 packageAbiOverride); 14471 14472 if (DEBUG_EPHEMERAL && ephemeral) { 14473 Slog.v(TAG, "pkgLite for install: " + pkgLite); 14474 } 14475 14476 /* 14477 * If we have too little free space, try to free cache 14478 * before giving up. 14479 */ 14480 if (!origin.staged && pkgLite.recommendedInstallLocation 14481 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 14482 // TODO: focus freeing disk space on the target device 14483 final StorageManager storage = StorageManager.from(mContext); 14484 final long lowThreshold = storage.getStorageLowBytes( 14485 Environment.getDataDirectory()); 14486 14487 final long sizeBytes = mContainerService.calculateInstalledSize( 14488 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 14489 14490 try { 14491 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0); 14492 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 14493 installFlags, packageAbiOverride); 14494 } catch (InstallerException e) { 14495 Slog.w(TAG, "Failed to free cache", e); 14496 } 14497 14498 /* 14499 * The cache free must have deleted the file we 14500 * downloaded to install. 14501 * 14502 * TODO: fix the "freeCache" call to not delete 14503 * the file we care about. 14504 */ 14505 if (pkgLite.recommendedInstallLocation 14506 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 14507 pkgLite.recommendedInstallLocation 14508 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 14509 } 14510 } 14511 } 14512 14513 if (ret == PackageManager.INSTALL_SUCCEEDED) { 14514 int loc = pkgLite.recommendedInstallLocation; 14515 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 14516 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14517 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 14518 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 14519 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 14520 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 14521 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 14522 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 14523 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 14524 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 14525 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 14526 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 14527 } else { 14528 // Override with defaults if needed. 14529 loc = installLocationPolicy(pkgLite); 14530 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 14531 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 14532 } else if (!onSd && !onInt) { 14533 // Override install location with flags 14534 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 14535 // Set the flag to install on external media. 14536 installFlags |= PackageManager.INSTALL_EXTERNAL; 14537 installFlags &= ~PackageManager.INSTALL_INTERNAL; 14538 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 14539 if (DEBUG_EPHEMERAL) { 14540 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 14541 } 14542 installFlags |= PackageManager.INSTALL_INSTANT_APP; 14543 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 14544 |PackageManager.INSTALL_INTERNAL); 14545 } else { 14546 // Make sure the flag for installing on external 14547 // media is unset 14548 installFlags |= PackageManager.INSTALL_INTERNAL; 14549 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 14550 } 14551 } 14552 } 14553 } 14554 14555 final InstallArgs args = createInstallArgs(this); 14556 mArgs = args; 14557 14558 if (ret == PackageManager.INSTALL_SUCCEEDED) { 14559 // TODO: http://b/22976637 14560 // Apps installed for "all" users use the device owner to verify the app 14561 UserHandle verifierUser = getUser(); 14562 if (verifierUser == UserHandle.ALL) { 14563 verifierUser = UserHandle.SYSTEM; 14564 } 14565 14566 /* 14567 * Determine if we have any installed package verifiers. If we 14568 * do, then we'll defer to them to verify the packages. 14569 */ 14570 final int requiredUid = mRequiredVerifierPackage == null ? -1 14571 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 14572 verifierUser.getIdentifier()); 14573 if (!origin.existing && requiredUid != -1 14574 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 14575 final Intent verification = new Intent( 14576 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 14577 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14578 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 14579 PACKAGE_MIME_TYPE); 14580 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 14581 14582 // Query all live verifiers based on current user state 14583 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 14584 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 14585 14586 if (DEBUG_VERIFY) { 14587 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 14588 + verification.toString() + " with " + pkgLite.verifiers.length 14589 + " optional verifiers"); 14590 } 14591 14592 final int verificationId = mPendingVerificationToken++; 14593 14594 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 14595 14596 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 14597 installerPackageName); 14598 14599 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 14600 installFlags); 14601 14602 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 14603 pkgLite.packageName); 14604 14605 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 14606 pkgLite.versionCode); 14607 14608 if (verificationInfo != null) { 14609 if (verificationInfo.originatingUri != null) { 14610 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 14611 verificationInfo.originatingUri); 14612 } 14613 if (verificationInfo.referrer != null) { 14614 verification.putExtra(Intent.EXTRA_REFERRER, 14615 verificationInfo.referrer); 14616 } 14617 if (verificationInfo.originatingUid >= 0) { 14618 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 14619 verificationInfo.originatingUid); 14620 } 14621 if (verificationInfo.installerUid >= 0) { 14622 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 14623 verificationInfo.installerUid); 14624 } 14625 } 14626 14627 final PackageVerificationState verificationState = new PackageVerificationState( 14628 requiredUid, args); 14629 14630 mPendingVerification.append(verificationId, verificationState); 14631 14632 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 14633 receivers, verificationState); 14634 14635 /* 14636 * If any sufficient verifiers were listed in the package 14637 * manifest, attempt to ask them. 14638 */ 14639 if (sufficientVerifiers != null) { 14640 final int N = sufficientVerifiers.size(); 14641 if (N == 0) { 14642 Slog.i(TAG, "Additional verifiers required, but none installed."); 14643 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 14644 } else { 14645 for (int i = 0; i < N; i++) { 14646 final ComponentName verifierComponent = sufficientVerifiers.get(i); 14647 14648 final Intent sufficientIntent = new Intent(verification); 14649 sufficientIntent.setComponent(verifierComponent); 14650 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 14651 } 14652 } 14653 } 14654 14655 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 14656 mRequiredVerifierPackage, receivers); 14657 if (ret == PackageManager.INSTALL_SUCCEEDED 14658 && mRequiredVerifierPackage != null) { 14659 Trace.asyncTraceBegin( 14660 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 14661 /* 14662 * Send the intent to the required verification agent, 14663 * but only start the verification timeout after the 14664 * target BroadcastReceivers have run. 14665 */ 14666 verification.setComponent(requiredVerifierComponent); 14667 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 14668 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 14669 new BroadcastReceiver() { 14670 @Override 14671 public void onReceive(Context context, Intent intent) { 14672 final Message msg = mHandler 14673 .obtainMessage(CHECK_PENDING_VERIFICATION); 14674 msg.arg1 = verificationId; 14675 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 14676 } 14677 }, null, 0, null, null); 14678 14679 /* 14680 * We don't want the copy to proceed until verification 14681 * succeeds, so null out this field. 14682 */ 14683 mArgs = null; 14684 } 14685 } else { 14686 /* 14687 * No package verification is enabled, so immediately start 14688 * the remote call to initiate copy using temporary file. 14689 */ 14690 ret = args.copyApk(mContainerService, true); 14691 } 14692 } 14693 14694 mRet = ret; 14695 } 14696 14697 @Override 14698 void handleReturnCode() { 14699 // If mArgs is null, then MCS couldn't be reached. When it 14700 // reconnects, it will try again to install. At that point, this 14701 // will succeed. 14702 if (mArgs != null) { 14703 processPendingInstall(mArgs, mRet); 14704 } 14705 } 14706 14707 @Override 14708 void handleServiceError() { 14709 mArgs = createInstallArgs(this); 14710 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 14711 } 14712 14713 public boolean isForwardLocked() { 14714 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14715 } 14716 } 14717 14718 /** 14719 * Used during creation of InstallArgs 14720 * 14721 * @param installFlags package installation flags 14722 * @return true if should be installed on external storage 14723 */ 14724 private static boolean installOnExternalAsec(int installFlags) { 14725 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 14726 return false; 14727 } 14728 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 14729 return true; 14730 } 14731 return false; 14732 } 14733 14734 /** 14735 * Used during creation of InstallArgs 14736 * 14737 * @param installFlags package installation flags 14738 * @return true if should be installed as forward locked 14739 */ 14740 private static boolean installForwardLocked(int installFlags) { 14741 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14742 } 14743 14744 private InstallArgs createInstallArgs(InstallParams params) { 14745 if (params.move != null) { 14746 return new MoveInstallArgs(params); 14747 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 14748 return new AsecInstallArgs(params); 14749 } else { 14750 return new FileInstallArgs(params); 14751 } 14752 } 14753 14754 /** 14755 * Create args that describe an existing installed package. Typically used 14756 * when cleaning up old installs, or used as a move source. 14757 */ 14758 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 14759 String resourcePath, String[] instructionSets) { 14760 final boolean isInAsec; 14761 if (installOnExternalAsec(installFlags)) { 14762 /* Apps on SD card are always in ASEC containers. */ 14763 isInAsec = true; 14764 } else if (installForwardLocked(installFlags) 14765 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 14766 /* 14767 * Forward-locked apps are only in ASEC containers if they're the 14768 * new style 14769 */ 14770 isInAsec = true; 14771 } else { 14772 isInAsec = false; 14773 } 14774 14775 if (isInAsec) { 14776 return new AsecInstallArgs(codePath, instructionSets, 14777 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 14778 } else { 14779 return new FileInstallArgs(codePath, resourcePath, instructionSets); 14780 } 14781 } 14782 14783 static abstract class InstallArgs { 14784 /** @see InstallParams#origin */ 14785 final OriginInfo origin; 14786 /** @see InstallParams#move */ 14787 final MoveInfo move; 14788 14789 final IPackageInstallObserver2 observer; 14790 // Always refers to PackageManager flags only 14791 final int installFlags; 14792 final String installerPackageName; 14793 final String volumeUuid; 14794 final UserHandle user; 14795 final String abiOverride; 14796 final String[] installGrantPermissions; 14797 /** If non-null, drop an async trace when the install completes */ 14798 final String traceMethod; 14799 final int traceCookie; 14800 final Certificate[][] certificates; 14801 final int installReason; 14802 14803 // The list of instruction sets supported by this app. This is currently 14804 // only used during the rmdex() phase to clean up resources. We can get rid of this 14805 // if we move dex files under the common app path. 14806 /* nullable */ String[] instructionSets; 14807 14808 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 14809 int installFlags, String installerPackageName, String volumeUuid, 14810 UserHandle user, String[] instructionSets, 14811 String abiOverride, String[] installGrantPermissions, 14812 String traceMethod, int traceCookie, Certificate[][] certificates, 14813 int installReason) { 14814 this.origin = origin; 14815 this.move = move; 14816 this.installFlags = installFlags; 14817 this.observer = observer; 14818 this.installerPackageName = installerPackageName; 14819 this.volumeUuid = volumeUuid; 14820 this.user = user; 14821 this.instructionSets = instructionSets; 14822 this.abiOverride = abiOverride; 14823 this.installGrantPermissions = installGrantPermissions; 14824 this.traceMethod = traceMethod; 14825 this.traceCookie = traceCookie; 14826 this.certificates = certificates; 14827 this.installReason = installReason; 14828 } 14829 14830 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 14831 abstract int doPreInstall(int status); 14832 14833 /** 14834 * Rename package into final resting place. All paths on the given 14835 * scanned package should be updated to reflect the rename. 14836 */ 14837 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 14838 abstract int doPostInstall(int status, int uid); 14839 14840 /** @see PackageSettingBase#codePathString */ 14841 abstract String getCodePath(); 14842 /** @see PackageSettingBase#resourcePathString */ 14843 abstract String getResourcePath(); 14844 14845 // Need installer lock especially for dex file removal. 14846 abstract void cleanUpResourcesLI(); 14847 abstract boolean doPostDeleteLI(boolean delete); 14848 14849 /** 14850 * Called before the source arguments are copied. This is used mostly 14851 * for MoveParams when it needs to read the source file to put it in the 14852 * destination. 14853 */ 14854 int doPreCopy() { 14855 return PackageManager.INSTALL_SUCCEEDED; 14856 } 14857 14858 /** 14859 * Called after the source arguments are copied. This is used mostly for 14860 * MoveParams when it needs to read the source file to put it in the 14861 * destination. 14862 */ 14863 int doPostCopy(int uid) { 14864 return PackageManager.INSTALL_SUCCEEDED; 14865 } 14866 14867 protected boolean isFwdLocked() { 14868 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14869 } 14870 14871 protected boolean isExternalAsec() { 14872 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14873 } 14874 14875 protected boolean isEphemeral() { 14876 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14877 } 14878 14879 UserHandle getUser() { 14880 return user; 14881 } 14882 } 14883 14884 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 14885 if (!allCodePaths.isEmpty()) { 14886 if (instructionSets == null) { 14887 throw new IllegalStateException("instructionSet == null"); 14888 } 14889 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 14890 for (String codePath : allCodePaths) { 14891 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 14892 try { 14893 mInstaller.rmdex(codePath, dexCodeInstructionSet); 14894 } catch (InstallerException ignored) { 14895 } 14896 } 14897 } 14898 } 14899 } 14900 14901 /** 14902 * Logic to handle installation of non-ASEC applications, including copying 14903 * and renaming logic. 14904 */ 14905 class FileInstallArgs extends InstallArgs { 14906 private File codeFile; 14907 private File resourceFile; 14908 14909 // Example topology: 14910 // /data/app/com.example/base.apk 14911 // /data/app/com.example/split_foo.apk 14912 // /data/app/com.example/lib/arm/libfoo.so 14913 // /data/app/com.example/lib/arm64/libfoo.so 14914 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 14915 14916 /** New install */ 14917 FileInstallArgs(InstallParams params) { 14918 super(params.origin, params.move, params.observer, params.installFlags, 14919 params.installerPackageName, params.volumeUuid, 14920 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 14921 params.grantedRuntimePermissions, 14922 params.traceMethod, params.traceCookie, params.certificates, 14923 params.installReason); 14924 if (isFwdLocked()) { 14925 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 14926 } 14927 } 14928 14929 /** Existing install */ 14930 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 14931 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 14932 null, null, null, 0, null /*certificates*/, 14933 PackageManager.INSTALL_REASON_UNKNOWN); 14934 this.codeFile = (codePath != null) ? new File(codePath) : null; 14935 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 14936 } 14937 14938 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14939 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 14940 try { 14941 return doCopyApk(imcs, temp); 14942 } finally { 14943 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14944 } 14945 } 14946 14947 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14948 if (origin.staged) { 14949 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 14950 codeFile = origin.file; 14951 resourceFile = origin.file; 14952 return PackageManager.INSTALL_SUCCEEDED; 14953 } 14954 14955 try { 14956 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14957 final File tempDir = 14958 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 14959 codeFile = tempDir; 14960 resourceFile = tempDir; 14961 } catch (IOException e) { 14962 Slog.w(TAG, "Failed to create copy file: " + e); 14963 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 14964 } 14965 14966 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 14967 @Override 14968 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 14969 if (!FileUtils.isValidExtFilename(name)) { 14970 throw new IllegalArgumentException("Invalid filename: " + name); 14971 } 14972 try { 14973 final File file = new File(codeFile, name); 14974 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 14975 O_RDWR | O_CREAT, 0644); 14976 Os.chmod(file.getAbsolutePath(), 0644); 14977 return new ParcelFileDescriptor(fd); 14978 } catch (ErrnoException e) { 14979 throw new RemoteException("Failed to open: " + e.getMessage()); 14980 } 14981 } 14982 }; 14983 14984 int ret = PackageManager.INSTALL_SUCCEEDED; 14985 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 14986 if (ret != PackageManager.INSTALL_SUCCEEDED) { 14987 Slog.e(TAG, "Failed to copy package"); 14988 return ret; 14989 } 14990 14991 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 14992 NativeLibraryHelper.Handle handle = null; 14993 try { 14994 handle = NativeLibraryHelper.Handle.create(codeFile); 14995 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 14996 abiOverride); 14997 } catch (IOException e) { 14998 Slog.e(TAG, "Copying native libraries failed", e); 14999 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 15000 } finally { 15001 IoUtils.closeQuietly(handle); 15002 } 15003 15004 return ret; 15005 } 15006 15007 int doPreInstall(int status) { 15008 if (status != PackageManager.INSTALL_SUCCEEDED) { 15009 cleanUp(); 15010 } 15011 return status; 15012 } 15013 15014 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15015 if (status != PackageManager.INSTALL_SUCCEEDED) { 15016 cleanUp(); 15017 return false; 15018 } 15019 15020 final File targetDir = codeFile.getParentFile(); 15021 final File beforeCodeFile = codeFile; 15022 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 15023 15024 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 15025 try { 15026 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 15027 } catch (ErrnoException e) { 15028 Slog.w(TAG, "Failed to rename", e); 15029 return false; 15030 } 15031 15032 if (!SELinux.restoreconRecursive(afterCodeFile)) { 15033 Slog.w(TAG, "Failed to restorecon"); 15034 return false; 15035 } 15036 15037 // Reflect the rename internally 15038 codeFile = afterCodeFile; 15039 resourceFile = afterCodeFile; 15040 15041 // Reflect the rename in scanned details 15042 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 15043 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 15044 afterCodeFile, pkg.baseCodePath)); 15045 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 15046 afterCodeFile, pkg.splitCodePaths)); 15047 15048 // Reflect the rename in app info 15049 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15050 pkg.setApplicationInfoCodePath(pkg.codePath); 15051 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15052 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15053 pkg.setApplicationInfoResourcePath(pkg.codePath); 15054 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15055 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15056 15057 return true; 15058 } 15059 15060 int doPostInstall(int status, int uid) { 15061 if (status != PackageManager.INSTALL_SUCCEEDED) { 15062 cleanUp(); 15063 } 15064 return status; 15065 } 15066 15067 @Override 15068 String getCodePath() { 15069 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 15070 } 15071 15072 @Override 15073 String getResourcePath() { 15074 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 15075 } 15076 15077 private boolean cleanUp() { 15078 if (codeFile == null || !codeFile.exists()) { 15079 return false; 15080 } 15081 15082 removeCodePathLI(codeFile); 15083 15084 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 15085 resourceFile.delete(); 15086 } 15087 15088 return true; 15089 } 15090 15091 void cleanUpResourcesLI() { 15092 // Try enumerating all code paths before deleting 15093 List<String> allCodePaths = Collections.EMPTY_LIST; 15094 if (codeFile != null && codeFile.exists()) { 15095 try { 15096 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 15097 allCodePaths = pkg.getAllCodePaths(); 15098 } catch (PackageParserException e) { 15099 // Ignored; we tried our best 15100 } 15101 } 15102 15103 cleanUp(); 15104 removeDexFiles(allCodePaths, instructionSets); 15105 } 15106 15107 boolean doPostDeleteLI(boolean delete) { 15108 // XXX err, shouldn't we respect the delete flag? 15109 cleanUpResourcesLI(); 15110 return true; 15111 } 15112 } 15113 15114 private boolean isAsecExternal(String cid) { 15115 final String asecPath = PackageHelper.getSdFilesystem(cid); 15116 return !asecPath.startsWith(mAsecInternalPath); 15117 } 15118 15119 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 15120 PackageManagerException { 15121 if (copyRet < 0) { 15122 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 15123 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 15124 throw new PackageManagerException(copyRet, message); 15125 } 15126 } 15127 } 15128 15129 /** 15130 * Extract the StorageManagerService "container ID" from the full code path of an 15131 * .apk. 15132 */ 15133 static String cidFromCodePath(String fullCodePath) { 15134 int eidx = fullCodePath.lastIndexOf("/"); 15135 String subStr1 = fullCodePath.substring(0, eidx); 15136 int sidx = subStr1.lastIndexOf("/"); 15137 return subStr1.substring(sidx+1, eidx); 15138 } 15139 15140 /** 15141 * Logic to handle installation of ASEC applications, including copying and 15142 * renaming logic. 15143 */ 15144 class AsecInstallArgs extends InstallArgs { 15145 static final String RES_FILE_NAME = "pkg.apk"; 15146 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 15147 15148 String cid; 15149 String packagePath; 15150 String resourcePath; 15151 15152 /** New install */ 15153 AsecInstallArgs(InstallParams params) { 15154 super(params.origin, params.move, params.observer, params.installFlags, 15155 params.installerPackageName, params.volumeUuid, 15156 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 15157 params.grantedRuntimePermissions, 15158 params.traceMethod, params.traceCookie, params.certificates, 15159 params.installReason); 15160 } 15161 15162 /** Existing install */ 15163 AsecInstallArgs(String fullCodePath, String[] instructionSets, 15164 boolean isExternal, boolean isForwardLocked) { 15165 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 15166 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 15167 instructionSets, null, null, null, 0, null /*certificates*/, 15168 PackageManager.INSTALL_REASON_UNKNOWN); 15169 // Hackily pretend we're still looking at a full code path 15170 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 15171 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 15172 } 15173 15174 // Extract cid from fullCodePath 15175 int eidx = fullCodePath.lastIndexOf("/"); 15176 String subStr1 = fullCodePath.substring(0, eidx); 15177 int sidx = subStr1.lastIndexOf("/"); 15178 cid = subStr1.substring(sidx+1, eidx); 15179 setMountPath(subStr1); 15180 } 15181 15182 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 15183 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 15184 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 15185 instructionSets, null, null, null, 0, null /*certificates*/, 15186 PackageManager.INSTALL_REASON_UNKNOWN); 15187 this.cid = cid; 15188 setMountPath(PackageHelper.getSdDir(cid)); 15189 } 15190 15191 void createCopyFile() { 15192 cid = mInstallerService.allocateExternalStageCidLegacy(); 15193 } 15194 15195 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 15196 if (origin.staged && origin.cid != null) { 15197 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 15198 cid = origin.cid; 15199 setMountPath(PackageHelper.getSdDir(cid)); 15200 return PackageManager.INSTALL_SUCCEEDED; 15201 } 15202 15203 if (temp) { 15204 createCopyFile(); 15205 } else { 15206 /* 15207 * Pre-emptively destroy the container since it's destroyed if 15208 * copying fails due to it existing anyway. 15209 */ 15210 PackageHelper.destroySdDir(cid); 15211 } 15212 15213 final String newMountPath = imcs.copyPackageToContainer( 15214 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 15215 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 15216 15217 if (newMountPath != null) { 15218 setMountPath(newMountPath); 15219 return PackageManager.INSTALL_SUCCEEDED; 15220 } else { 15221 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15222 } 15223 } 15224 15225 @Override 15226 String getCodePath() { 15227 return packagePath; 15228 } 15229 15230 @Override 15231 String getResourcePath() { 15232 return resourcePath; 15233 } 15234 15235 int doPreInstall(int status) { 15236 if (status != PackageManager.INSTALL_SUCCEEDED) { 15237 // Destroy container 15238 PackageHelper.destroySdDir(cid); 15239 } else { 15240 boolean mounted = PackageHelper.isContainerMounted(cid); 15241 if (!mounted) { 15242 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 15243 Process.SYSTEM_UID); 15244 if (newMountPath != null) { 15245 setMountPath(newMountPath); 15246 } else { 15247 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15248 } 15249 } 15250 } 15251 return status; 15252 } 15253 15254 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15255 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 15256 String newMountPath = null; 15257 if (PackageHelper.isContainerMounted(cid)) { 15258 // Unmount the container 15259 if (!PackageHelper.unMountSdDir(cid)) { 15260 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 15261 return false; 15262 } 15263 } 15264 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 15265 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 15266 " which might be stale. Will try to clean up."); 15267 // Clean up the stale container and proceed to recreate. 15268 if (!PackageHelper.destroySdDir(newCacheId)) { 15269 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 15270 return false; 15271 } 15272 // Successfully cleaned up stale container. Try to rename again. 15273 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 15274 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 15275 + " inspite of cleaning it up."); 15276 return false; 15277 } 15278 } 15279 if (!PackageHelper.isContainerMounted(newCacheId)) { 15280 Slog.w(TAG, "Mounting container " + newCacheId); 15281 newMountPath = PackageHelper.mountSdDir(newCacheId, 15282 getEncryptKey(), Process.SYSTEM_UID); 15283 } else { 15284 newMountPath = PackageHelper.getSdDir(newCacheId); 15285 } 15286 if (newMountPath == null) { 15287 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 15288 return false; 15289 } 15290 Log.i(TAG, "Succesfully renamed " + cid + 15291 " to " + newCacheId + 15292 " at new path: " + newMountPath); 15293 cid = newCacheId; 15294 15295 final File beforeCodeFile = new File(packagePath); 15296 setMountPath(newMountPath); 15297 final File afterCodeFile = new File(packagePath); 15298 15299 // Reflect the rename in scanned details 15300 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 15301 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 15302 afterCodeFile, pkg.baseCodePath)); 15303 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 15304 afterCodeFile, pkg.splitCodePaths)); 15305 15306 // Reflect the rename in app info 15307 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15308 pkg.setApplicationInfoCodePath(pkg.codePath); 15309 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15310 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15311 pkg.setApplicationInfoResourcePath(pkg.codePath); 15312 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15313 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15314 15315 return true; 15316 } 15317 15318 private void setMountPath(String mountPath) { 15319 final File mountFile = new File(mountPath); 15320 15321 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 15322 if (monolithicFile.exists()) { 15323 packagePath = monolithicFile.getAbsolutePath(); 15324 if (isFwdLocked()) { 15325 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 15326 } else { 15327 resourcePath = packagePath; 15328 } 15329 } else { 15330 packagePath = mountFile.getAbsolutePath(); 15331 resourcePath = packagePath; 15332 } 15333 } 15334 15335 int doPostInstall(int status, int uid) { 15336 if (status != PackageManager.INSTALL_SUCCEEDED) { 15337 cleanUp(); 15338 } else { 15339 final int groupOwner; 15340 final String protectedFile; 15341 if (isFwdLocked()) { 15342 groupOwner = UserHandle.getSharedAppGid(uid); 15343 protectedFile = RES_FILE_NAME; 15344 } else { 15345 groupOwner = -1; 15346 protectedFile = null; 15347 } 15348 15349 if (uid < Process.FIRST_APPLICATION_UID 15350 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 15351 Slog.e(TAG, "Failed to finalize " + cid); 15352 PackageHelper.destroySdDir(cid); 15353 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15354 } 15355 15356 boolean mounted = PackageHelper.isContainerMounted(cid); 15357 if (!mounted) { 15358 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 15359 } 15360 } 15361 return status; 15362 } 15363 15364 private void cleanUp() { 15365 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 15366 15367 // Destroy secure container 15368 PackageHelper.destroySdDir(cid); 15369 } 15370 15371 private List<String> getAllCodePaths() { 15372 final File codeFile = new File(getCodePath()); 15373 if (codeFile != null && codeFile.exists()) { 15374 try { 15375 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 15376 return pkg.getAllCodePaths(); 15377 } catch (PackageParserException e) { 15378 // Ignored; we tried our best 15379 } 15380 } 15381 return Collections.EMPTY_LIST; 15382 } 15383 15384 void cleanUpResourcesLI() { 15385 // Enumerate all code paths before deleting 15386 cleanUpResourcesLI(getAllCodePaths()); 15387 } 15388 15389 private void cleanUpResourcesLI(List<String> allCodePaths) { 15390 cleanUp(); 15391 removeDexFiles(allCodePaths, instructionSets); 15392 } 15393 15394 String getPackageName() { 15395 return getAsecPackageName(cid); 15396 } 15397 15398 boolean doPostDeleteLI(boolean delete) { 15399 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 15400 final List<String> allCodePaths = getAllCodePaths(); 15401 boolean mounted = PackageHelper.isContainerMounted(cid); 15402 if (mounted) { 15403 // Unmount first 15404 if (PackageHelper.unMountSdDir(cid)) { 15405 mounted = false; 15406 } 15407 } 15408 if (!mounted && delete) { 15409 cleanUpResourcesLI(allCodePaths); 15410 } 15411 return !mounted; 15412 } 15413 15414 @Override 15415 int doPreCopy() { 15416 if (isFwdLocked()) { 15417 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 15418 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 15419 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15420 } 15421 } 15422 15423 return PackageManager.INSTALL_SUCCEEDED; 15424 } 15425 15426 @Override 15427 int doPostCopy(int uid) { 15428 if (isFwdLocked()) { 15429 if (uid < Process.FIRST_APPLICATION_UID 15430 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 15431 RES_FILE_NAME)) { 15432 Slog.e(TAG, "Failed to finalize " + cid); 15433 PackageHelper.destroySdDir(cid); 15434 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15435 } 15436 } 15437 15438 return PackageManager.INSTALL_SUCCEEDED; 15439 } 15440 } 15441 15442 /** 15443 * Logic to handle movement of existing installed applications. 15444 */ 15445 class MoveInstallArgs extends InstallArgs { 15446 private File codeFile; 15447 private File resourceFile; 15448 15449 /** New install */ 15450 MoveInstallArgs(InstallParams params) { 15451 super(params.origin, params.move, params.observer, params.installFlags, 15452 params.installerPackageName, params.volumeUuid, 15453 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 15454 params.grantedRuntimePermissions, 15455 params.traceMethod, params.traceCookie, params.certificates, 15456 params.installReason); 15457 } 15458 15459 int copyApk(IMediaContainerService imcs, boolean temp) { 15460 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 15461 + move.fromUuid + " to " + move.toUuid); 15462 synchronized (mInstaller) { 15463 try { 15464 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 15465 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 15466 } catch (InstallerException e) { 15467 Slog.w(TAG, "Failed to move app", e); 15468 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 15469 } 15470 } 15471 15472 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 15473 resourceFile = codeFile; 15474 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 15475 15476 return PackageManager.INSTALL_SUCCEEDED; 15477 } 15478 15479 int doPreInstall(int status) { 15480 if (status != PackageManager.INSTALL_SUCCEEDED) { 15481 cleanUp(move.toUuid); 15482 } 15483 return status; 15484 } 15485 15486 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15487 if (status != PackageManager.INSTALL_SUCCEEDED) { 15488 cleanUp(move.toUuid); 15489 return false; 15490 } 15491 15492 // Reflect the move in app info 15493 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15494 pkg.setApplicationInfoCodePath(pkg.codePath); 15495 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15496 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15497 pkg.setApplicationInfoResourcePath(pkg.codePath); 15498 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15499 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15500 15501 return true; 15502 } 15503 15504 int doPostInstall(int status, int uid) { 15505 if (status == PackageManager.INSTALL_SUCCEEDED) { 15506 cleanUp(move.fromUuid); 15507 } else { 15508 cleanUp(move.toUuid); 15509 } 15510 return status; 15511 } 15512 15513 @Override 15514 String getCodePath() { 15515 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 15516 } 15517 15518 @Override 15519 String getResourcePath() { 15520 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 15521 } 15522 15523 private boolean cleanUp(String volumeUuid) { 15524 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 15525 move.dataAppName); 15526 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 15527 final int[] userIds = sUserManager.getUserIds(); 15528 synchronized (mInstallLock) { 15529 // Clean up both app data and code 15530 // All package moves are frozen until finished 15531 for (int userId : userIds) { 15532 try { 15533 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 15534 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 15535 } catch (InstallerException e) { 15536 Slog.w(TAG, String.valueOf(e)); 15537 } 15538 } 15539 removeCodePathLI(codeFile); 15540 } 15541 return true; 15542 } 15543 15544 void cleanUpResourcesLI() { 15545 throw new UnsupportedOperationException(); 15546 } 15547 15548 boolean doPostDeleteLI(boolean delete) { 15549 throw new UnsupportedOperationException(); 15550 } 15551 } 15552 15553 static String getAsecPackageName(String packageCid) { 15554 int idx = packageCid.lastIndexOf("-"); 15555 if (idx == -1) { 15556 return packageCid; 15557 } 15558 return packageCid.substring(0, idx); 15559 } 15560 15561 // Utility method used to create code paths based on package name and available index. 15562 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 15563 String idxStr = ""; 15564 int idx = 1; 15565 // Fall back to default value of idx=1 if prefix is not 15566 // part of oldCodePath 15567 if (oldCodePath != null) { 15568 String subStr = oldCodePath; 15569 // Drop the suffix right away 15570 if (suffix != null && subStr.endsWith(suffix)) { 15571 subStr = subStr.substring(0, subStr.length() - suffix.length()); 15572 } 15573 // If oldCodePath already contains prefix find out the 15574 // ending index to either increment or decrement. 15575 int sidx = subStr.lastIndexOf(prefix); 15576 if (sidx != -1) { 15577 subStr = subStr.substring(sidx + prefix.length()); 15578 if (subStr != null) { 15579 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 15580 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 15581 } 15582 try { 15583 idx = Integer.parseInt(subStr); 15584 if (idx <= 1) { 15585 idx++; 15586 } else { 15587 idx--; 15588 } 15589 } catch(NumberFormatException e) { 15590 } 15591 } 15592 } 15593 } 15594 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 15595 return prefix + idxStr; 15596 } 15597 15598 private File getNextCodePath(File targetDir, String packageName) { 15599 File result; 15600 SecureRandom random = new SecureRandom(); 15601 byte[] bytes = new byte[16]; 15602 do { 15603 random.nextBytes(bytes); 15604 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); 15605 result = new File(targetDir, packageName + "-" + suffix); 15606 } while (result.exists()); 15607 return result; 15608 } 15609 15610 // Utility method that returns the relative package path with respect 15611 // to the installation directory. Like say for /data/data/com.test-1.apk 15612 // string com.test-1 is returned. 15613 static String deriveCodePathName(String codePath) { 15614 if (codePath == null) { 15615 return null; 15616 } 15617 final File codeFile = new File(codePath); 15618 final String name = codeFile.getName(); 15619 if (codeFile.isDirectory()) { 15620 return name; 15621 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 15622 final int lastDot = name.lastIndexOf('.'); 15623 return name.substring(0, lastDot); 15624 } else { 15625 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 15626 return null; 15627 } 15628 } 15629 15630 static class PackageInstalledInfo { 15631 String name; 15632 int uid; 15633 // The set of users that originally had this package installed. 15634 int[] origUsers; 15635 // The set of users that now have this package installed. 15636 int[] newUsers; 15637 PackageParser.Package pkg; 15638 int returnCode; 15639 String returnMsg; 15640 PackageRemovedInfo removedInfo; 15641 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 15642 15643 public void setError(int code, String msg) { 15644 setReturnCode(code); 15645 setReturnMessage(msg); 15646 Slog.w(TAG, msg); 15647 } 15648 15649 public void setError(String msg, PackageParserException e) { 15650 setReturnCode(e.error); 15651 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 15652 Slog.w(TAG, msg, e); 15653 } 15654 15655 public void setError(String msg, PackageManagerException e) { 15656 returnCode = e.error; 15657 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 15658 Slog.w(TAG, msg, e); 15659 } 15660 15661 public void setReturnCode(int returnCode) { 15662 this.returnCode = returnCode; 15663 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 15664 for (int i = 0; i < childCount; i++) { 15665 addedChildPackages.valueAt(i).returnCode = returnCode; 15666 } 15667 } 15668 15669 private void setReturnMessage(String returnMsg) { 15670 this.returnMsg = returnMsg; 15671 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 15672 for (int i = 0; i < childCount; i++) { 15673 addedChildPackages.valueAt(i).returnMsg = returnMsg; 15674 } 15675 } 15676 15677 // In some error cases we want to convey more info back to the observer 15678 String origPackage; 15679 String origPermission; 15680 } 15681 15682 /* 15683 * Install a non-existing package. 15684 */ 15685 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 15686 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 15687 PackageInstalledInfo res, int installReason) { 15688 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 15689 15690 // Remember this for later, in case we need to rollback this install 15691 String pkgName = pkg.packageName; 15692 15693 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 15694 15695 synchronized(mPackages) { 15696 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName); 15697 if (renamedPackage != null) { 15698 // A package with the same name is already installed, though 15699 // it has been renamed to an older name. The package we 15700 // are trying to install should be installed as an update to 15701 // the existing one, but that has not been requested, so bail. 15702 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 15703 + " without first uninstalling package running as " 15704 + renamedPackage); 15705 return; 15706 } 15707 if (mPackages.containsKey(pkgName)) { 15708 // Don't allow installation over an existing package with the same name. 15709 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 15710 + " without first uninstalling."); 15711 return; 15712 } 15713 } 15714 15715 try { 15716 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 15717 System.currentTimeMillis(), user); 15718 15719 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason); 15720 15721 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 15722 prepareAppDataAfterInstallLIF(newPackage); 15723 15724 } else { 15725 // Remove package from internal structures, but keep around any 15726 // data that might have already existed 15727 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 15728 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 15729 } 15730 } catch (PackageManagerException e) { 15731 res.setError("Package couldn't be installed in " + pkg.codePath, e); 15732 } 15733 15734 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15735 } 15736 15737 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 15738 // Can't rotate keys during boot or if sharedUser. 15739 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 15740 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 15741 return false; 15742 } 15743 // app is using upgradeKeySets; make sure all are valid 15744 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15745 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 15746 for (int i = 0; i < upgradeKeySets.length; i++) { 15747 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 15748 Slog.wtf(TAG, "Package " 15749 + (oldPs.name != null ? oldPs.name : "<null>") 15750 + " contains upgrade-key-set reference to unknown key-set: " 15751 + upgradeKeySets[i] 15752 + " reverting to signatures check."); 15753 return false; 15754 } 15755 } 15756 return true; 15757 } 15758 15759 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 15760 // Upgrade keysets are being used. Determine if new package has a superset of the 15761 // required keys. 15762 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 15763 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15764 for (int i = 0; i < upgradeKeySets.length; i++) { 15765 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 15766 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 15767 return true; 15768 } 15769 } 15770 return false; 15771 } 15772 15773 private static void updateDigest(MessageDigest digest, File file) throws IOException { 15774 try (DigestInputStream digestStream = 15775 new DigestInputStream(new FileInputStream(file), digest)) { 15776 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 15777 } 15778 } 15779 15780 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 15781 UserHandle user, String installerPackageName, PackageInstalledInfo res, 15782 int installReason) { 15783 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 15784 15785 final PackageParser.Package oldPackage; 15786 final String pkgName = pkg.packageName; 15787 final int[] allUsers; 15788 final int[] installedUsers; 15789 15790 synchronized(mPackages) { 15791 oldPackage = mPackages.get(pkgName); 15792 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 15793 15794 // don't allow upgrade to target a release SDK from a pre-release SDK 15795 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 15796 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 15797 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 15798 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 15799 if (oldTargetsPreRelease 15800 && !newTargetsPreRelease 15801 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 15802 Slog.w(TAG, "Can't install package targeting released sdk"); 15803 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 15804 return; 15805 } 15806 15807 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15808 15809 // don't allow an upgrade from full to ephemeral 15810 if (isInstantApp && !ps.getInstantApp(user.getIdentifier())) { 15811 // can't downgrade from full to instant 15812 Slog.w(TAG, "Can't replace app with instant app: " + pkgName); 15813 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 15814 return; 15815 } 15816 15817 // verify signatures are valid 15818 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 15819 if (!checkUpgradeKeySetLP(ps, pkg)) { 15820 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 15821 "New package not signed by keys specified by upgrade-keysets: " 15822 + pkgName); 15823 return; 15824 } 15825 } else { 15826 // default to original signature matching 15827 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 15828 != PackageManager.SIGNATURE_MATCH) { 15829 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 15830 "New package has a different signature: " + pkgName); 15831 return; 15832 } 15833 } 15834 15835 // don't allow a system upgrade unless the upgrade hash matches 15836 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 15837 byte[] digestBytes = null; 15838 try { 15839 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 15840 updateDigest(digest, new File(pkg.baseCodePath)); 15841 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 15842 for (String path : pkg.splitCodePaths) { 15843 updateDigest(digest, new File(path)); 15844 } 15845 } 15846 digestBytes = digest.digest(); 15847 } catch (NoSuchAlgorithmException | IOException e) { 15848 res.setError(INSTALL_FAILED_INVALID_APK, 15849 "Could not compute hash: " + pkgName); 15850 return; 15851 } 15852 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 15853 res.setError(INSTALL_FAILED_INVALID_APK, 15854 "New package fails restrict-update check: " + pkgName); 15855 return; 15856 } 15857 // retain upgrade restriction 15858 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 15859 } 15860 15861 // Check for shared user id changes 15862 String invalidPackageName = 15863 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 15864 if (invalidPackageName != null) { 15865 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 15866 "Package " + invalidPackageName + " tried to change user " 15867 + oldPackage.mSharedUserId); 15868 return; 15869 } 15870 15871 // In case of rollback, remember per-user/profile install state 15872 allUsers = sUserManager.getUserIds(); 15873 installedUsers = ps.queryInstalledUsers(allUsers, true); 15874 } 15875 15876 // Update what is removed 15877 res.removedInfo = new PackageRemovedInfo(); 15878 res.removedInfo.uid = oldPackage.applicationInfo.uid; 15879 res.removedInfo.removedPackage = oldPackage.packageName; 15880 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null; 15881 res.removedInfo.isUpdate = true; 15882 res.removedInfo.origUsers = installedUsers; 15883 final PackageSetting ps = mSettings.getPackageLPr(pkgName); 15884 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length); 15885 for (int i = 0; i < installedUsers.length; i++) { 15886 final int userId = installedUsers[i]; 15887 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId)); 15888 } 15889 15890 final int childCount = (oldPackage.childPackages != null) 15891 ? oldPackage.childPackages.size() : 0; 15892 for (int i = 0; i < childCount; i++) { 15893 boolean childPackageUpdated = false; 15894 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 15895 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 15896 if (res.addedChildPackages != null) { 15897 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15898 if (childRes != null) { 15899 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 15900 childRes.removedInfo.removedPackage = childPkg.packageName; 15901 childRes.removedInfo.isUpdate = true; 15902 childRes.removedInfo.installReasons = res.removedInfo.installReasons; 15903 childPackageUpdated = true; 15904 } 15905 } 15906 if (!childPackageUpdated) { 15907 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 15908 childRemovedRes.removedPackage = childPkg.packageName; 15909 childRemovedRes.isUpdate = false; 15910 childRemovedRes.dataRemoved = true; 15911 synchronized (mPackages) { 15912 if (childPs != null) { 15913 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 15914 } 15915 } 15916 if (res.removedInfo.removedChildPackages == null) { 15917 res.removedInfo.removedChildPackages = new ArrayMap<>(); 15918 } 15919 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 15920 } 15921 } 15922 15923 boolean sysPkg = (isSystemApp(oldPackage)); 15924 if (sysPkg) { 15925 // Set the system/privileged flags as needed 15926 final boolean privileged = 15927 (oldPackage.applicationInfo.privateFlags 15928 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15929 final int systemPolicyFlags = policyFlags 15930 | PackageParser.PARSE_IS_SYSTEM 15931 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 15932 15933 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 15934 user, allUsers, installerPackageName, res, installReason); 15935 } else { 15936 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 15937 user, allUsers, installerPackageName, res, installReason); 15938 } 15939 } 15940 15941 public List<String> getPreviousCodePaths(String packageName) { 15942 final PackageSetting ps = mSettings.mPackages.get(packageName); 15943 final List<String> result = new ArrayList<String>(); 15944 if (ps != null && ps.oldCodePaths != null) { 15945 result.addAll(ps.oldCodePaths); 15946 } 15947 return result; 15948 } 15949 15950 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 15951 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 15952 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 15953 int installReason) { 15954 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 15955 + deletedPackage); 15956 15957 String pkgName = deletedPackage.packageName; 15958 boolean deletedPkg = true; 15959 boolean addedPkg = false; 15960 boolean updatedSettings = false; 15961 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 15962 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 15963 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 15964 15965 final long origUpdateTime = (pkg.mExtras != null) 15966 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 15967 15968 // First delete the existing package while retaining the data directory 15969 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 15970 res.removedInfo, true, pkg)) { 15971 // If the existing package wasn't successfully deleted 15972 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 15973 deletedPkg = false; 15974 } else { 15975 // Successfully deleted the old package; proceed with replace. 15976 15977 // If deleted package lived in a container, give users a chance to 15978 // relinquish resources before killing. 15979 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 15980 if (DEBUG_INSTALL) { 15981 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 15982 } 15983 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 15984 final ArrayList<String> pkgList = new ArrayList<String>(1); 15985 pkgList.add(deletedPackage.applicationInfo.packageName); 15986 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 15987 } 15988 15989 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 15990 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 15991 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 15992 15993 try { 15994 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 15995 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 15996 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 15997 installReason); 15998 15999 // Update the in-memory copy of the previous code paths. 16000 PackageSetting ps = mSettings.mPackages.get(pkgName); 16001 if (!killApp) { 16002 if (ps.oldCodePaths == null) { 16003 ps.oldCodePaths = new ArraySet<>(); 16004 } 16005 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 16006 if (deletedPackage.splitCodePaths != null) { 16007 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 16008 } 16009 } else { 16010 ps.oldCodePaths = null; 16011 } 16012 if (ps.childPackageNames != null) { 16013 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 16014 final String childPkgName = ps.childPackageNames.get(i); 16015 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 16016 childPs.oldCodePaths = ps.oldCodePaths; 16017 } 16018 } 16019 // set instant app status, but, only if it's explicitly specified 16020 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 16021 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0; 16022 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp); 16023 prepareAppDataAfterInstallLIF(newPackage); 16024 addedPkg = true; 16025 } catch (PackageManagerException e) { 16026 res.setError("Package couldn't be installed in " + pkg.codePath, e); 16027 } 16028 } 16029 16030 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 16031 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 16032 16033 // Revert all internal state mutations and added folders for the failed install 16034 if (addedPkg) { 16035 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 16036 res.removedInfo, true, null); 16037 } 16038 16039 // Restore the old package 16040 if (deletedPkg) { 16041 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 16042 File restoreFile = new File(deletedPackage.codePath); 16043 // Parse old package 16044 boolean oldExternal = isExternal(deletedPackage); 16045 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 16046 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 16047 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 16048 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 16049 try { 16050 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 16051 null); 16052 } catch (PackageManagerException e) { 16053 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 16054 + e.getMessage()); 16055 return; 16056 } 16057 16058 synchronized (mPackages) { 16059 // Ensure the installer package name up to date 16060 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 16061 16062 // Update permissions for restored package 16063 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 16064 16065 mSettings.writeLPr(); 16066 } 16067 16068 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 16069 } 16070 } else { 16071 synchronized (mPackages) { 16072 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName); 16073 if (ps != null) { 16074 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16075 if (res.removedInfo.removedChildPackages != null) { 16076 final int childCount = res.removedInfo.removedChildPackages.size(); 16077 // Iterate in reverse as we may modify the collection 16078 for (int i = childCount - 1; i >= 0; i--) { 16079 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 16080 if (res.addedChildPackages.containsKey(childPackageName)) { 16081 res.removedInfo.removedChildPackages.removeAt(i); 16082 } else { 16083 PackageRemovedInfo childInfo = res.removedInfo 16084 .removedChildPackages.valueAt(i); 16085 childInfo.removedForAllUsers = mPackages.get( 16086 childInfo.removedPackage) == null; 16087 } 16088 } 16089 } 16090 } 16091 } 16092 } 16093 } 16094 16095 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 16096 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 16097 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 16098 int installReason) { 16099 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 16100 + ", old=" + deletedPackage); 16101 16102 final boolean disabledSystem; 16103 16104 // Remove existing system package 16105 removePackageLI(deletedPackage, true); 16106 16107 synchronized (mPackages) { 16108 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 16109 } 16110 if (!disabledSystem) { 16111 // We didn't need to disable the .apk as a current system package, 16112 // which means we are replacing another update that is already 16113 // installed. We need to make sure to delete the older one's .apk. 16114 res.removedInfo.args = createInstallArgsForExisting(0, 16115 deletedPackage.applicationInfo.getCodePath(), 16116 deletedPackage.applicationInfo.getResourcePath(), 16117 getAppDexInstructionSets(deletedPackage.applicationInfo)); 16118 } else { 16119 res.removedInfo.args = null; 16120 } 16121 16122 // Successfully disabled the old package. Now proceed with re-installation 16123 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 16124 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16125 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 16126 16127 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16128 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 16129 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 16130 16131 PackageParser.Package newPackage = null; 16132 try { 16133 // Add the package to the internal data structures 16134 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 16135 16136 // Set the update and install times 16137 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 16138 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 16139 System.currentTimeMillis()); 16140 16141 // Update the package dynamic state if succeeded 16142 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 16143 // Now that the install succeeded make sure we remove data 16144 // directories for any child package the update removed. 16145 final int deletedChildCount = (deletedPackage.childPackages != null) 16146 ? deletedPackage.childPackages.size() : 0; 16147 final int newChildCount = (newPackage.childPackages != null) 16148 ? newPackage.childPackages.size() : 0; 16149 for (int i = 0; i < deletedChildCount; i++) { 16150 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 16151 boolean childPackageDeleted = true; 16152 for (int j = 0; j < newChildCount; j++) { 16153 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 16154 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 16155 childPackageDeleted = false; 16156 break; 16157 } 16158 } 16159 if (childPackageDeleted) { 16160 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 16161 deletedChildPkg.packageName); 16162 if (ps != null && res.removedInfo.removedChildPackages != null) { 16163 PackageRemovedInfo removedChildRes = res.removedInfo 16164 .removedChildPackages.get(deletedChildPkg.packageName); 16165 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 16166 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 16167 } 16168 } 16169 } 16170 16171 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 16172 installReason); 16173 prepareAppDataAfterInstallLIF(newPackage); 16174 } 16175 } catch (PackageManagerException e) { 16176 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 16177 res.setError("Package couldn't be installed in " + pkg.codePath, e); 16178 } 16179 16180 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 16181 // Re installation failed. Restore old information 16182 // Remove new pkg information 16183 if (newPackage != null) { 16184 removeInstalledPackageLI(newPackage, true); 16185 } 16186 // Add back the old system package 16187 try { 16188 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 16189 } catch (PackageManagerException e) { 16190 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 16191 } 16192 16193 synchronized (mPackages) { 16194 if (disabledSystem) { 16195 enableSystemPackageLPw(deletedPackage); 16196 } 16197 16198 // Ensure the installer package name up to date 16199 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 16200 16201 // Update permissions for restored package 16202 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 16203 16204 mSettings.writeLPr(); 16205 } 16206 16207 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 16208 + " after failed upgrade"); 16209 } 16210 } 16211 16212 /** 16213 * Checks whether the parent or any of the child packages have a change shared 16214 * user. For a package to be a valid update the shred users of the parent and 16215 * the children should match. We may later support changing child shared users. 16216 * @param oldPkg The updated package. 16217 * @param newPkg The update package. 16218 * @return The shared user that change between the versions. 16219 */ 16220 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 16221 PackageParser.Package newPkg) { 16222 // Check parent shared user 16223 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 16224 return newPkg.packageName; 16225 } 16226 // Check child shared users 16227 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 16228 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 16229 for (int i = 0; i < newChildCount; i++) { 16230 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 16231 // If this child was present, did it have the same shared user? 16232 for (int j = 0; j < oldChildCount; j++) { 16233 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 16234 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 16235 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 16236 return newChildPkg.packageName; 16237 } 16238 } 16239 } 16240 return null; 16241 } 16242 16243 private void removeNativeBinariesLI(PackageSetting ps) { 16244 // Remove the lib path for the parent package 16245 if (ps != null) { 16246 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 16247 // Remove the lib path for the child packages 16248 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 16249 for (int i = 0; i < childCount; i++) { 16250 PackageSetting childPs = null; 16251 synchronized (mPackages) { 16252 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 16253 } 16254 if (childPs != null) { 16255 NativeLibraryHelper.removeNativeBinariesLI(childPs 16256 .legacyNativeLibraryPathString); 16257 } 16258 } 16259 } 16260 } 16261 16262 private void enableSystemPackageLPw(PackageParser.Package pkg) { 16263 // Enable the parent package 16264 mSettings.enableSystemPackageLPw(pkg.packageName); 16265 // Enable the child packages 16266 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16267 for (int i = 0; i < childCount; i++) { 16268 PackageParser.Package childPkg = pkg.childPackages.get(i); 16269 mSettings.enableSystemPackageLPw(childPkg.packageName); 16270 } 16271 } 16272 16273 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 16274 PackageParser.Package newPkg) { 16275 // Disable the parent package (parent always replaced) 16276 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 16277 // Disable the child packages 16278 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 16279 for (int i = 0; i < childCount; i++) { 16280 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 16281 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 16282 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 16283 } 16284 return disabled; 16285 } 16286 16287 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 16288 String installerPackageName) { 16289 // Enable the parent package 16290 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 16291 // Enable the child packages 16292 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16293 for (int i = 0; i < childCount; i++) { 16294 PackageParser.Package childPkg = pkg.childPackages.get(i); 16295 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 16296 } 16297 } 16298 16299 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 16300 // Collect all used permissions in the UID 16301 ArraySet<String> usedPermissions = new ArraySet<>(); 16302 final int packageCount = su.packages.size(); 16303 for (int i = 0; i < packageCount; i++) { 16304 PackageSetting ps = su.packages.valueAt(i); 16305 if (ps.pkg == null) { 16306 continue; 16307 } 16308 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 16309 for (int j = 0; j < requestedPermCount; j++) { 16310 String permission = ps.pkg.requestedPermissions.get(j); 16311 BasePermission bp = mSettings.mPermissions.get(permission); 16312 if (bp != null) { 16313 usedPermissions.add(permission); 16314 } 16315 } 16316 } 16317 16318 PermissionsState permissionsState = su.getPermissionsState(); 16319 // Prune install permissions 16320 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 16321 final int installPermCount = installPermStates.size(); 16322 for (int i = installPermCount - 1; i >= 0; i--) { 16323 PermissionState permissionState = installPermStates.get(i); 16324 if (!usedPermissions.contains(permissionState.getName())) { 16325 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 16326 if (bp != null) { 16327 permissionsState.revokeInstallPermission(bp); 16328 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 16329 PackageManager.MASK_PERMISSION_FLAGS, 0); 16330 } 16331 } 16332 } 16333 16334 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 16335 16336 // Prune runtime permissions 16337 for (int userId : allUserIds) { 16338 List<PermissionState> runtimePermStates = permissionsState 16339 .getRuntimePermissionStates(userId); 16340 final int runtimePermCount = runtimePermStates.size(); 16341 for (int i = runtimePermCount - 1; i >= 0; i--) { 16342 PermissionState permissionState = runtimePermStates.get(i); 16343 if (!usedPermissions.contains(permissionState.getName())) { 16344 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 16345 if (bp != null) { 16346 permissionsState.revokeRuntimePermission(bp, userId); 16347 permissionsState.updatePermissionFlags(bp, userId, 16348 PackageManager.MASK_PERMISSION_FLAGS, 0); 16349 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 16350 runtimePermissionChangedUserIds, userId); 16351 } 16352 } 16353 } 16354 } 16355 16356 return runtimePermissionChangedUserIds; 16357 } 16358 16359 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 16360 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) { 16361 // Update the parent package setting 16362 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 16363 res, user, installReason); 16364 // Update the child packages setting 16365 final int childCount = (newPackage.childPackages != null) 16366 ? newPackage.childPackages.size() : 0; 16367 for (int i = 0; i < childCount; i++) { 16368 PackageParser.Package childPackage = newPackage.childPackages.get(i); 16369 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 16370 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 16371 childRes.origUsers, childRes, user, installReason); 16372 } 16373 } 16374 16375 private void updateSettingsInternalLI(PackageParser.Package newPackage, 16376 String installerPackageName, int[] allUsers, int[] installedForUsers, 16377 PackageInstalledInfo res, UserHandle user, int installReason) { 16378 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 16379 16380 String pkgName = newPackage.packageName; 16381 synchronized (mPackages) { 16382 //write settings. the installStatus will be incomplete at this stage. 16383 //note that the new package setting would have already been 16384 //added to mPackages. It hasn't been persisted yet. 16385 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 16386 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 16387 mSettings.writeLPr(); 16388 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16389 } 16390 16391 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 16392 synchronized (mPackages) { 16393 updatePermissionsLPw(newPackage.packageName, newPackage, 16394 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 16395 ? UPDATE_PERMISSIONS_ALL : 0)); 16396 // For system-bundled packages, we assume that installing an upgraded version 16397 // of the package implies that the user actually wants to run that new code, 16398 // so we enable the package. 16399 PackageSetting ps = mSettings.mPackages.get(pkgName); 16400 final int userId = user.getIdentifier(); 16401 if (ps != null) { 16402 if (isSystemApp(newPackage)) { 16403 if (DEBUG_INSTALL) { 16404 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 16405 } 16406 // Enable system package for requested users 16407 if (res.origUsers != null) { 16408 for (int origUserId : res.origUsers) { 16409 if (userId == UserHandle.USER_ALL || userId == origUserId) { 16410 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 16411 origUserId, installerPackageName); 16412 } 16413 } 16414 } 16415 // Also convey the prior install/uninstall state 16416 if (allUsers != null && installedForUsers != null) { 16417 for (int currentUserId : allUsers) { 16418 final boolean installed = ArrayUtils.contains( 16419 installedForUsers, currentUserId); 16420 if (DEBUG_INSTALL) { 16421 Slog.d(TAG, " user " + currentUserId + " => " + installed); 16422 } 16423 ps.setInstalled(installed, currentUserId); 16424 } 16425 // these install state changes will be persisted in the 16426 // upcoming call to mSettings.writeLPr(). 16427 } 16428 } 16429 // It's implied that when a user requests installation, they want the app to be 16430 // installed and enabled. 16431 if (userId != UserHandle.USER_ALL) { 16432 ps.setInstalled(true, userId); 16433 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 16434 } 16435 16436 // When replacing an existing package, preserve the original install reason for all 16437 // users that had the package installed before. 16438 final Set<Integer> previousUserIds = new ArraySet<>(); 16439 if (res.removedInfo != null && res.removedInfo.installReasons != null) { 16440 final int installReasonCount = res.removedInfo.installReasons.size(); 16441 for (int i = 0; i < installReasonCount; i++) { 16442 final int previousUserId = res.removedInfo.installReasons.keyAt(i); 16443 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i); 16444 ps.setInstallReason(previousInstallReason, previousUserId); 16445 previousUserIds.add(previousUserId); 16446 } 16447 } 16448 16449 // Set install reason for users that are having the package newly installed. 16450 if (userId == UserHandle.USER_ALL) { 16451 for (int currentUserId : sUserManager.getUserIds()) { 16452 if (!previousUserIds.contains(currentUserId)) { 16453 ps.setInstallReason(installReason, currentUserId); 16454 } 16455 } 16456 } else if (!previousUserIds.contains(userId)) { 16457 ps.setInstallReason(installReason, userId); 16458 } 16459 } 16460 res.name = pkgName; 16461 res.uid = newPackage.applicationInfo.uid; 16462 res.pkg = newPackage; 16463 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 16464 mSettings.setInstallerPackageName(pkgName, installerPackageName); 16465 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16466 //to update install status 16467 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 16468 mSettings.writeLPr(); 16469 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16470 } 16471 16472 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16473 } 16474 16475 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 16476 try { 16477 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 16478 installPackageLI(args, res); 16479 } finally { 16480 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16481 } 16482 } 16483 16484 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 16485 final int installFlags = args.installFlags; 16486 final String installerPackageName = args.installerPackageName; 16487 final String volumeUuid = args.volumeUuid; 16488 final File tmpPackageFile = new File(args.getCodePath()); 16489 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 16490 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 16491 || (args.volumeUuid != null)); 16492 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); 16493 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); 16494 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 16495 boolean replace = false; 16496 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 16497 if (args.move != null) { 16498 // moving a complete application; perform an initial scan on the new install location 16499 scanFlags |= SCAN_INITIAL; 16500 } 16501 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 16502 scanFlags |= SCAN_DONT_KILL_APP; 16503 } 16504 if (instantApp) { 16505 scanFlags |= SCAN_AS_INSTANT_APP; 16506 } 16507 if (fullApp) { 16508 scanFlags |= SCAN_AS_FULL_APP; 16509 } 16510 16511 // Result object to be returned 16512 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16513 16514 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 16515 16516 // Sanity check 16517 if (instantApp && (forwardLocked || onExternal)) { 16518 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 16519 + " external=" + onExternal); 16520 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 16521 return; 16522 } 16523 16524 // Retrieve PackageSettings and parse package 16525 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 16526 | PackageParser.PARSE_ENFORCE_CODE 16527 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 16528 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 16529 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0) 16530 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 16531 PackageParser pp = new PackageParser(); 16532 pp.setSeparateProcesses(mSeparateProcesses); 16533 pp.setDisplayMetrics(mMetrics); 16534 16535 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 16536 final PackageParser.Package pkg; 16537 try { 16538 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 16539 } catch (PackageParserException e) { 16540 res.setError("Failed parse during installPackageLI", e); 16541 return; 16542 } finally { 16543 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16544 } 16545 16546// // Ephemeral apps must have target SDK >= O. 16547// // TODO: Update conditional and error message when O gets locked down 16548// if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) { 16549// res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID, 16550// "Ephemeral apps must have target SDK version of at least O"); 16551// return; 16552// } 16553 16554 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16555 // Static shared libraries have synthetic package names 16556 renameStaticSharedLibraryPackage(pkg); 16557 16558 // No static shared libs on external storage 16559 if (onExternal) { 16560 Slog.i(TAG, "Static shared libs can only be installed on internal storage."); 16561 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 16562 "Packages declaring static-shared libs cannot be updated"); 16563 return; 16564 } 16565 } 16566 16567 // If we are installing a clustered package add results for the children 16568 if (pkg.childPackages != null) { 16569 synchronized (mPackages) { 16570 final int childCount = pkg.childPackages.size(); 16571 for (int i = 0; i < childCount; i++) { 16572 PackageParser.Package childPkg = pkg.childPackages.get(i); 16573 PackageInstalledInfo childRes = new PackageInstalledInfo(); 16574 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16575 childRes.pkg = childPkg; 16576 childRes.name = childPkg.packageName; 16577 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 16578 if (childPs != null) { 16579 childRes.origUsers = childPs.queryInstalledUsers( 16580 sUserManager.getUserIds(), true); 16581 } 16582 if ((mPackages.containsKey(childPkg.packageName))) { 16583 childRes.removedInfo = new PackageRemovedInfo(); 16584 childRes.removedInfo.removedPackage = childPkg.packageName; 16585 } 16586 if (res.addedChildPackages == null) { 16587 res.addedChildPackages = new ArrayMap<>(); 16588 } 16589 res.addedChildPackages.put(childPkg.packageName, childRes); 16590 } 16591 } 16592 } 16593 16594 // If package doesn't declare API override, mark that we have an install 16595 // time CPU ABI override. 16596 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 16597 pkg.cpuAbiOverride = args.abiOverride; 16598 } 16599 16600 String pkgName = res.name = pkg.packageName; 16601 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 16602 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 16603 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 16604 return; 16605 } 16606 } 16607 16608 try { 16609 // either use what we've been given or parse directly from the APK 16610 if (args.certificates != null) { 16611 try { 16612 PackageParser.populateCertificates(pkg, args.certificates); 16613 } catch (PackageParserException e) { 16614 // there was something wrong with the certificates we were given; 16615 // try to pull them from the APK 16616 PackageParser.collectCertificates(pkg, parseFlags); 16617 } 16618 } else { 16619 PackageParser.collectCertificates(pkg, parseFlags); 16620 } 16621 } catch (PackageParserException e) { 16622 res.setError("Failed collect during installPackageLI", e); 16623 return; 16624 } 16625 16626 // Get rid of all references to package scan path via parser. 16627 pp = null; 16628 String oldCodePath = null; 16629 boolean systemApp = false; 16630 synchronized (mPackages) { 16631 // Check if installing already existing package 16632 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 16633 String oldName = mSettings.getRenamedPackageLPr(pkgName); 16634 if (pkg.mOriginalPackages != null 16635 && pkg.mOriginalPackages.contains(oldName) 16636 && mPackages.containsKey(oldName)) { 16637 // This package is derived from an original package, 16638 // and this device has been updating from that original 16639 // name. We must continue using the original name, so 16640 // rename the new package here. 16641 pkg.setPackageName(oldName); 16642 pkgName = pkg.packageName; 16643 replace = true; 16644 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 16645 + oldName + " pkgName=" + pkgName); 16646 } else if (mPackages.containsKey(pkgName)) { 16647 // This package, under its official name, already exists 16648 // on the device; we should replace it. 16649 replace = true; 16650 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 16651 } 16652 16653 // Child packages are installed through the parent package 16654 if (pkg.parentPackage != null) { 16655 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 16656 "Package " + pkg.packageName + " is child of package " 16657 + pkg.parentPackage.parentPackage + ". Child packages " 16658 + "can be updated only through the parent package."); 16659 return; 16660 } 16661 16662 if (replace) { 16663 // Prevent apps opting out from runtime permissions 16664 PackageParser.Package oldPackage = mPackages.get(pkgName); 16665 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 16666 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 16667 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 16668 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 16669 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 16670 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 16671 + " doesn't support runtime permissions but the old" 16672 + " target SDK " + oldTargetSdk + " does."); 16673 return; 16674 } 16675 16676 // Prevent installing of child packages 16677 if (oldPackage.parentPackage != null) { 16678 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 16679 "Package " + pkg.packageName + " is child of package " 16680 + oldPackage.parentPackage + ". Child packages " 16681 + "can be updated only through the parent package."); 16682 return; 16683 } 16684 } 16685 } 16686 16687 PackageSetting ps = mSettings.mPackages.get(pkgName); 16688 if (ps != null) { 16689 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 16690 16691 // Static shared libs have same package with different versions where 16692 // we internally use a synthetic package name to allow multiple versions 16693 // of the same package, therefore we need to compare signatures against 16694 // the package setting for the latest library version. 16695 PackageSetting signatureCheckPs = ps; 16696 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16697 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg); 16698 if (libraryEntry != null) { 16699 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk); 16700 } 16701 } 16702 16703 // Quick sanity check that we're signed correctly if updating; 16704 // we'll check this again later when scanning, but we want to 16705 // bail early here before tripping over redefined permissions. 16706 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) { 16707 if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) { 16708 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 16709 + pkg.packageName + " upgrade keys do not match the " 16710 + "previously installed version"); 16711 return; 16712 } 16713 } else { 16714 try { 16715 verifySignaturesLP(signatureCheckPs, pkg); 16716 } catch (PackageManagerException e) { 16717 res.setError(e.error, e.getMessage()); 16718 return; 16719 } 16720 } 16721 16722 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 16723 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 16724 systemApp = (ps.pkg.applicationInfo.flags & 16725 ApplicationInfo.FLAG_SYSTEM) != 0; 16726 } 16727 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 16728 } 16729 16730 // Check whether the newly-scanned package wants to define an already-defined perm 16731 int N = pkg.permissions.size(); 16732 for (int i = N-1; i >= 0; i--) { 16733 PackageParser.Permission perm = pkg.permissions.get(i); 16734 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 16735 if (bp != null) { 16736 // If the defining package is signed with our cert, it's okay. This 16737 // also includes the "updating the same package" case, of course. 16738 // "updating same package" could also involve key-rotation. 16739 final boolean sigsOk; 16740 if (bp.sourcePackage.equals(pkg.packageName) 16741 && (bp.packageSetting instanceof PackageSetting) 16742 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 16743 scanFlags))) { 16744 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 16745 } else { 16746 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 16747 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 16748 } 16749 if (!sigsOk) { 16750 // If the owning package is the system itself, we log but allow 16751 // install to proceed; we fail the install on all other permission 16752 // redefinitions. 16753 if (!bp.sourcePackage.equals("android")) { 16754 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 16755 + pkg.packageName + " attempting to redeclare permission " 16756 + perm.info.name + " already owned by " + bp.sourcePackage); 16757 res.origPermission = perm.info.name; 16758 res.origPackage = bp.sourcePackage; 16759 return; 16760 } else { 16761 Slog.w(TAG, "Package " + pkg.packageName 16762 + " attempting to redeclare system permission " 16763 + perm.info.name + "; ignoring new declaration"); 16764 pkg.permissions.remove(i); 16765 } 16766 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { 16767 // Prevent apps to change protection level to dangerous from any other 16768 // type as this would allow a privilege escalation where an app adds a 16769 // normal/signature permission in other app's group and later redefines 16770 // it as dangerous leading to the group auto-grant. 16771 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) 16772 == PermissionInfo.PROTECTION_DANGEROUS) { 16773 if (bp != null && !bp.isRuntime()) { 16774 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a " 16775 + "non-runtime permission " + perm.info.name 16776 + " to runtime; keeping old protection level"); 16777 perm.info.protectionLevel = bp.protectionLevel; 16778 } 16779 } 16780 } 16781 } 16782 } 16783 } 16784 16785 if (systemApp) { 16786 if (onExternal) { 16787 // Abort update; system app can't be replaced with app on sdcard 16788 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 16789 "Cannot install updates to system apps on sdcard"); 16790 return; 16791 } else if (instantApp) { 16792 // Abort update; system app can't be replaced with an instant app 16793 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID, 16794 "Cannot update a system app with an instant app"); 16795 return; 16796 } 16797 } 16798 16799 if (args.move != null) { 16800 // We did an in-place move, so dex is ready to roll 16801 scanFlags |= SCAN_NO_DEX; 16802 scanFlags |= SCAN_MOVE; 16803 16804 synchronized (mPackages) { 16805 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16806 if (ps == null) { 16807 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 16808 "Missing settings for moved package " + pkgName); 16809 } 16810 16811 // We moved the entire application as-is, so bring over the 16812 // previously derived ABI information. 16813 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 16814 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 16815 } 16816 16817 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 16818 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 16819 scanFlags |= SCAN_NO_DEX; 16820 16821 try { 16822 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 16823 args.abiOverride : pkg.cpuAbiOverride); 16824 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 16825 true /*extractLibs*/, mAppLib32InstallDir); 16826 } catch (PackageManagerException pme) { 16827 Slog.e(TAG, "Error deriving application ABI", pme); 16828 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 16829 return; 16830 } 16831 16832 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 16833 // Do not run PackageDexOptimizer through the local performDexOpt 16834 // method because `pkg` may not be in `mPackages` yet. 16835 // 16836 // Also, don't fail application installs if the dexopt step fails. 16837 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 16838 null /* instructionSets */, false /* checkProfiles */, 16839 getCompilerFilterForReason(REASON_INSTALL), 16840 getOrCreateCompilerPackageStats(pkg)); 16841 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16842 16843 // Notify BackgroundDexOptJobService that the package has been changed. 16844 // If this is an update of a package which used to fail to compile, 16845 // BDOS will remove it from its blacklist. 16846 // TODO: Layering violation 16847 BackgroundDexOptJobService.notifyPackageChanged(pkg.packageName); 16848 } 16849 16850 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 16851 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 16852 return; 16853 } 16854 16855 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 16856 16857 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 16858 "installPackageLI")) { 16859 if (replace) { 16860 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16861 // Static libs have a synthetic package name containing the version 16862 // and cannot be updated as an update would get a new package name, 16863 // unless this is the exact same version code which is useful for 16864 // development. 16865 PackageParser.Package existingPkg = mPackages.get(pkg.packageName); 16866 if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) { 16867 res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring " 16868 + "static-shared libs cannot be updated"); 16869 return; 16870 } 16871 } 16872 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 16873 installerPackageName, res, args.installReason); 16874 } else { 16875 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 16876 args.user, installerPackageName, volumeUuid, res, args.installReason); 16877 } 16878 } 16879 synchronized (mPackages) { 16880 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16881 if (ps != null) { 16882 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 16883 } 16884 16885 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16886 for (int i = 0; i < childCount; i++) { 16887 PackageParser.Package childPkg = pkg.childPackages.get(i); 16888 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 16889 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 16890 if (childPs != null) { 16891 childRes.newUsers = childPs.queryInstalledUsers( 16892 sUserManager.getUserIds(), true); 16893 } 16894 } 16895 } 16896 } 16897 16898 private void startIntentFilterVerifications(int userId, boolean replacing, 16899 PackageParser.Package pkg) { 16900 if (mIntentFilterVerifierComponent == null) { 16901 Slog.w(TAG, "No IntentFilter verification will not be done as " 16902 + "there is no IntentFilterVerifier available!"); 16903 return; 16904 } 16905 16906 final int verifierUid = getPackageUid( 16907 mIntentFilterVerifierComponent.getPackageName(), 16908 MATCH_DEBUG_TRIAGED_MISSING, 16909 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 16910 16911 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 16912 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 16913 mHandler.sendMessage(msg); 16914 16915 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16916 for (int i = 0; i < childCount; i++) { 16917 PackageParser.Package childPkg = pkg.childPackages.get(i); 16918 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 16919 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 16920 mHandler.sendMessage(msg); 16921 } 16922 } 16923 16924 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 16925 PackageParser.Package pkg) { 16926 int size = pkg.activities.size(); 16927 if (size == 0) { 16928 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 16929 "No activity, so no need to verify any IntentFilter!"); 16930 return; 16931 } 16932 16933 final boolean hasDomainURLs = hasDomainURLs(pkg); 16934 if (!hasDomainURLs) { 16935 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 16936 "No domain URLs, so no need to verify any IntentFilter!"); 16937 return; 16938 } 16939 16940 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 16941 + " if any IntentFilter from the " + size 16942 + " Activities needs verification ..."); 16943 16944 int count = 0; 16945 final String packageName = pkg.packageName; 16946 16947 synchronized (mPackages) { 16948 // If this is a new install and we see that we've already run verification for this 16949 // package, we have nothing to do: it means the state was restored from backup. 16950 if (!replacing) { 16951 IntentFilterVerificationInfo ivi = 16952 mSettings.getIntentFilterVerificationLPr(packageName); 16953 if (ivi != null) { 16954 if (DEBUG_DOMAIN_VERIFICATION) { 16955 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 16956 + ivi.getStatusString()); 16957 } 16958 return; 16959 } 16960 } 16961 16962 // If any filters need to be verified, then all need to be. 16963 boolean needToVerify = false; 16964 for (PackageParser.Activity a : pkg.activities) { 16965 for (ActivityIntentInfo filter : a.intents) { 16966 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 16967 if (DEBUG_DOMAIN_VERIFICATION) { 16968 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 16969 } 16970 needToVerify = true; 16971 break; 16972 } 16973 } 16974 } 16975 16976 if (needToVerify) { 16977 final int verificationId = mIntentFilterVerificationToken++; 16978 for (PackageParser.Activity a : pkg.activities) { 16979 for (ActivityIntentInfo filter : a.intents) { 16980 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 16981 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 16982 "Verification needed for IntentFilter:" + filter.toString()); 16983 mIntentFilterVerifier.addOneIntentFilterVerification( 16984 verifierUid, userId, verificationId, filter, packageName); 16985 count++; 16986 } 16987 } 16988 } 16989 } 16990 } 16991 16992 if (count > 0) { 16993 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 16994 + " IntentFilter verification" + (count > 1 ? "s" : "") 16995 + " for userId:" + userId); 16996 mIntentFilterVerifier.startVerifications(userId); 16997 } else { 16998 if (DEBUG_DOMAIN_VERIFICATION) { 16999 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 17000 } 17001 } 17002 } 17003 17004 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 17005 final ComponentName cn = filter.activity.getComponentName(); 17006 final String packageName = cn.getPackageName(); 17007 17008 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 17009 packageName); 17010 if (ivi == null) { 17011 return true; 17012 } 17013 int status = ivi.getStatus(); 17014 switch (status) { 17015 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 17016 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 17017 return true; 17018 17019 default: 17020 // Nothing to do 17021 return false; 17022 } 17023 } 17024 17025 private static boolean isMultiArch(ApplicationInfo info) { 17026 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 17027 } 17028 17029 private static boolean isExternal(PackageParser.Package pkg) { 17030 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 17031 } 17032 17033 private static boolean isExternal(PackageSetting ps) { 17034 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 17035 } 17036 17037 private static boolean isSystemApp(PackageParser.Package pkg) { 17038 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 17039 } 17040 17041 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 17042 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 17043 } 17044 17045 private static boolean hasDomainURLs(PackageParser.Package pkg) { 17046 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 17047 } 17048 17049 private static boolean isSystemApp(PackageSetting ps) { 17050 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 17051 } 17052 17053 private static boolean isUpdatedSystemApp(PackageSetting ps) { 17054 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 17055 } 17056 17057 private int packageFlagsToInstallFlags(PackageSetting ps) { 17058 int installFlags = 0; 17059 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 17060 // This existing package was an external ASEC install when we have 17061 // the external flag without a UUID 17062 installFlags |= PackageManager.INSTALL_EXTERNAL; 17063 } 17064 if (ps.isForwardLocked()) { 17065 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 17066 } 17067 return installFlags; 17068 } 17069 17070 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 17071 if (isExternal(pkg)) { 17072 if (TextUtils.isEmpty(pkg.volumeUuid)) { 17073 return StorageManager.UUID_PRIMARY_PHYSICAL; 17074 } else { 17075 return pkg.volumeUuid; 17076 } 17077 } else { 17078 return StorageManager.UUID_PRIVATE_INTERNAL; 17079 } 17080 } 17081 17082 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 17083 if (isExternal(pkg)) { 17084 if (TextUtils.isEmpty(pkg.volumeUuid)) { 17085 return mSettings.getExternalVersion(); 17086 } else { 17087 return mSettings.findOrCreateVersion(pkg.volumeUuid); 17088 } 17089 } else { 17090 return mSettings.getInternalVersion(); 17091 } 17092 } 17093 17094 private void deleteTempPackageFiles() { 17095 final FilenameFilter filter = new FilenameFilter() { 17096 public boolean accept(File dir, String name) { 17097 return name.startsWith("vmdl") && name.endsWith(".tmp"); 17098 } 17099 }; 17100 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 17101 file.delete(); 17102 } 17103 } 17104 17105 @Override 17106 public void deletePackageAsUser(String packageName, int versionCode, 17107 IPackageDeleteObserver observer, int userId, int flags) { 17108 deletePackageVersioned(new VersionedPackage(packageName, versionCode), 17109 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags); 17110 } 17111 17112 @Override 17113 public void deletePackageVersioned(VersionedPackage versionedPackage, 17114 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 17115 mContext.enforceCallingOrSelfPermission( 17116 android.Manifest.permission.DELETE_PACKAGES, null); 17117 Preconditions.checkNotNull(versionedPackage); 17118 Preconditions.checkNotNull(observer); 17119 Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(), 17120 PackageManager.VERSION_CODE_HIGHEST, 17121 Integer.MAX_VALUE, "versionCode must be >= -1"); 17122 17123 final String packageName = versionedPackage.getPackageName(); 17124 // TODO: We will change version code to long, so in the new API it is long 17125 final int versionCode = (int) versionedPackage.getVersionCode(); 17126 final String internalPackageName; 17127 synchronized (mPackages) { 17128 // Normalize package name to handle renamed packages and static libs 17129 internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(), 17130 // TODO: We will change version code to long, so in the new API it is long 17131 (int) versionedPackage.getVersionCode()); 17132 } 17133 17134 final int uid = Binder.getCallingUid(); 17135 if (!isOrphaned(internalPackageName) 17136 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) { 17137 try { 17138 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 17139 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 17140 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 17141 observer.onUserActionRequired(intent); 17142 } catch (RemoteException re) { 17143 } 17144 return; 17145 } 17146 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 17147 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 17148 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 17149 mContext.enforceCallingOrSelfPermission( 17150 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 17151 "deletePackage for user " + userId); 17152 } 17153 17154 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 17155 try { 17156 observer.onPackageDeleted(packageName, 17157 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 17158 } catch (RemoteException re) { 17159 } 17160 return; 17161 } 17162 17163 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) { 17164 try { 17165 observer.onPackageDeleted(packageName, 17166 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 17167 } catch (RemoteException re) { 17168 } 17169 return; 17170 } 17171 17172 if (DEBUG_REMOVE) { 17173 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId 17174 + " deleteAllUsers: " + deleteAllUsers + " version=" 17175 + (versionCode == PackageManager.VERSION_CODE_HIGHEST 17176 ? "VERSION_CODE_HIGHEST" : versionCode)); 17177 } 17178 // Queue up an async operation since the package deletion may take a little while. 17179 mHandler.post(new Runnable() { 17180 public void run() { 17181 mHandler.removeCallbacks(this); 17182 int returnCode; 17183 if (!deleteAllUsers) { 17184 returnCode = deletePackageX(internalPackageName, versionCode, 17185 userId, deleteFlags); 17186 } else { 17187 int[] blockUninstallUserIds = getBlockUninstallForUsers( 17188 internalPackageName, users); 17189 // If nobody is blocking uninstall, proceed with delete for all users 17190 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 17191 returnCode = deletePackageX(internalPackageName, versionCode, 17192 userId, deleteFlags); 17193 } else { 17194 // Otherwise uninstall individually for users with blockUninstalls=false 17195 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 17196 for (int userId : users) { 17197 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 17198 returnCode = deletePackageX(internalPackageName, versionCode, 17199 userId, userFlags); 17200 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 17201 Slog.w(TAG, "Package delete failed for user " + userId 17202 + ", returnCode " + returnCode); 17203 } 17204 } 17205 } 17206 // The app has only been marked uninstalled for certain users. 17207 // We still need to report that delete was blocked 17208 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 17209 } 17210 } 17211 try { 17212 observer.onPackageDeleted(packageName, returnCode, null); 17213 } catch (RemoteException e) { 17214 Log.i(TAG, "Observer no longer exists."); 17215 } //end catch 17216 } //end run 17217 }); 17218 } 17219 17220 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) { 17221 if (pkg.staticSharedLibName != null) { 17222 return pkg.manifestPackageName; 17223 } 17224 return pkg.packageName; 17225 } 17226 17227 private String resolveInternalPackageNameLPr(String packageName, int versionCode) { 17228 // Handle renamed packages 17229 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName); 17230 packageName = normalizedPackageName != null ? normalizedPackageName : packageName; 17231 17232 // Is this a static library? 17233 SparseArray<SharedLibraryEntry> versionedLib = 17234 mStaticLibsByDeclaringPackage.get(packageName); 17235 if (versionedLib == null || versionedLib.size() <= 0) { 17236 return packageName; 17237 } 17238 17239 // Figure out which lib versions the caller can see 17240 SparseIntArray versionsCallerCanSee = null; 17241 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); 17242 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID 17243 && callingAppId != Process.ROOT_UID) { 17244 versionsCallerCanSee = new SparseIntArray(); 17245 String libName = versionedLib.valueAt(0).info.getName(); 17246 String[] uidPackages = getPackagesForUid(Binder.getCallingUid()); 17247 if (uidPackages != null) { 17248 for (String uidPackage : uidPackages) { 17249 PackageSetting ps = mSettings.getPackageLPr(uidPackage); 17250 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName); 17251 if (libIdx >= 0) { 17252 final int libVersion = ps.usesStaticLibrariesVersions[libIdx]; 17253 versionsCallerCanSee.append(libVersion, libVersion); 17254 } 17255 } 17256 } 17257 } 17258 17259 // Caller can see nothing - done 17260 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) { 17261 return packageName; 17262 } 17263 17264 // Find the version the caller can see and the app version code 17265 SharedLibraryEntry highestVersion = null; 17266 final int versionCount = versionedLib.size(); 17267 for (int i = 0; i < versionCount; i++) { 17268 SharedLibraryEntry libEntry = versionedLib.valueAt(i); 17269 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey( 17270 libEntry.info.getVersion()) < 0) { 17271 continue; 17272 } 17273 // TODO: We will change version code to long, so in the new API it is long 17274 final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode(); 17275 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) { 17276 if (libVersionCode == versionCode) { 17277 return libEntry.apk; 17278 } 17279 } else if (highestVersion == null) { 17280 highestVersion = libEntry; 17281 } else if (libVersionCode > highestVersion.info 17282 .getDeclaringPackage().getVersionCode()) { 17283 highestVersion = libEntry; 17284 } 17285 } 17286 17287 if (highestVersion != null) { 17288 return highestVersion.apk; 17289 } 17290 17291 return packageName; 17292 } 17293 17294 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) { 17295 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID 17296 || callingUid == Process.SYSTEM_UID) { 17297 return true; 17298 } 17299 final int callingUserId = UserHandle.getUserId(callingUid); 17300 // If the caller installed the pkgName, then allow it to silently uninstall. 17301 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) { 17302 return true; 17303 } 17304 17305 // Allow package verifier to silently uninstall. 17306 if (mRequiredVerifierPackage != null && 17307 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) { 17308 return true; 17309 } 17310 17311 // Allow package uninstaller to silently uninstall. 17312 if (mRequiredUninstallerPackage != null && 17313 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { 17314 return true; 17315 } 17316 17317 // Allow storage manager to silently uninstall. 17318 if (mStorageManagerPackage != null && 17319 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { 17320 return true; 17321 } 17322 return false; 17323 } 17324 17325 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 17326 int[] result = EMPTY_INT_ARRAY; 17327 for (int userId : userIds) { 17328 if (getBlockUninstallForUser(packageName, userId)) { 17329 result = ArrayUtils.appendInt(result, userId); 17330 } 17331 } 17332 return result; 17333 } 17334 17335 @Override 17336 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 17337 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 17338 } 17339 17340 private boolean isPackageDeviceAdmin(String packageName, int userId) { 17341 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 17342 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 17343 try { 17344 if (dpm != null) { 17345 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 17346 /* callingUserOnly =*/ false); 17347 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 17348 : deviceOwnerComponentName.getPackageName(); 17349 // Does the package contains the device owner? 17350 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 17351 // this check is probably not needed, since DO should be registered as a device 17352 // admin on some user too. (Original bug for this: b/17657954) 17353 if (packageName.equals(deviceOwnerPackageName)) { 17354 return true; 17355 } 17356 // Does it contain a device admin for any user? 17357 int[] users; 17358 if (userId == UserHandle.USER_ALL) { 17359 users = sUserManager.getUserIds(); 17360 } else { 17361 users = new int[]{userId}; 17362 } 17363 for (int i = 0; i < users.length; ++i) { 17364 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 17365 return true; 17366 } 17367 } 17368 } 17369 } catch (RemoteException e) { 17370 } 17371 return false; 17372 } 17373 17374 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 17375 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 17376 } 17377 17378 /** 17379 * This method is an internal method that could be get invoked either 17380 * to delete an installed package or to clean up a failed installation. 17381 * After deleting an installed package, a broadcast is sent to notify any 17382 * listeners that the package has been removed. For cleaning up a failed 17383 * installation, the broadcast is not necessary since the package's 17384 * installation wouldn't have sent the initial broadcast either 17385 * The key steps in deleting a package are 17386 * deleting the package information in internal structures like mPackages, 17387 * deleting the packages base directories through installd 17388 * updating mSettings to reflect current status 17389 * persisting settings for later use 17390 * sending a broadcast if necessary 17391 */ 17392 private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) { 17393 final PackageRemovedInfo info = new PackageRemovedInfo(); 17394 final boolean res; 17395 17396 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 17397 ? UserHandle.USER_ALL : userId; 17398 17399 if (isPackageDeviceAdmin(packageName, removeUser)) { 17400 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 17401 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 17402 } 17403 17404 PackageSetting uninstalledPs = null; 17405 17406 // for the uninstall-updates case and restricted profiles, remember the per- 17407 // user handle installed state 17408 int[] allUsers; 17409 synchronized (mPackages) { 17410 uninstalledPs = mSettings.mPackages.get(packageName); 17411 if (uninstalledPs == null) { 17412 Slog.w(TAG, "Not removing non-existent package " + packageName); 17413 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17414 } 17415 17416 if (versionCode != PackageManager.VERSION_CODE_HIGHEST 17417 && uninstalledPs.versionCode != versionCode) { 17418 Slog.w(TAG, "Not removing package " + packageName + " with versionCode " 17419 + uninstalledPs.versionCode + " != " + versionCode); 17420 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17421 } 17422 17423 // Static shared libs can be declared by any package, so let us not 17424 // allow removing a package if it provides a lib others depend on. 17425 PackageParser.Package pkg = mPackages.get(packageName); 17426 if (pkg != null && pkg.staticSharedLibName != null) { 17427 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName, 17428 pkg.staticSharedLibVersion); 17429 if (libEntry != null) { 17430 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr( 17431 libEntry.info, 0, userId); 17432 if (!ArrayUtils.isEmpty(libClientPackages)) { 17433 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName 17434 + " hosting lib " + libEntry.info.getName() + " version " 17435 + libEntry.info.getVersion() + " used by " + libClientPackages); 17436 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY; 17437 } 17438 } 17439 } 17440 17441 allUsers = sUserManager.getUserIds(); 17442 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 17443 } 17444 17445 final int freezeUser; 17446 if (isUpdatedSystemApp(uninstalledPs) 17447 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 17448 // We're downgrading a system app, which will apply to all users, so 17449 // freeze them all during the downgrade 17450 freezeUser = UserHandle.USER_ALL; 17451 } else { 17452 freezeUser = removeUser; 17453 } 17454 17455 synchronized (mInstallLock) { 17456 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 17457 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 17458 deleteFlags, "deletePackageX")) { 17459 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 17460 deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null); 17461 } 17462 synchronized (mPackages) { 17463 if (res) { 17464 mInstantAppRegistry.onPackageUninstalledLPw(uninstalledPs.pkg, 17465 info.removedUsers); 17466 } 17467 } 17468 } 17469 17470 if (res) { 17471 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 17472 info.sendPackageRemovedBroadcasts(killApp); 17473 info.sendSystemPackageUpdatedBroadcasts(); 17474 info.sendSystemPackageAppearedBroadcasts(); 17475 } 17476 // Force a gc here. 17477 Runtime.getRuntime().gc(); 17478 // Delete the resources here after sending the broadcast to let 17479 // other processes clean up before deleting resources. 17480 if (info.args != null) { 17481 synchronized (mInstallLock) { 17482 info.args.doPostDeleteLI(true); 17483 } 17484 } 17485 17486 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17487 } 17488 17489 class PackageRemovedInfo { 17490 String removedPackage; 17491 int uid = -1; 17492 int removedAppId = -1; 17493 int[] origUsers; 17494 int[] removedUsers = null; 17495 SparseArray<Integer> installReasons; 17496 boolean isRemovedPackageSystemUpdate = false; 17497 boolean isUpdate; 17498 boolean dataRemoved; 17499 boolean removedForAllUsers; 17500 boolean isStaticSharedLib; 17501 // Clean up resources deleted packages. 17502 InstallArgs args = null; 17503 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 17504 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 17505 17506 void sendPackageRemovedBroadcasts(boolean killApp) { 17507 sendPackageRemovedBroadcastInternal(killApp); 17508 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 17509 for (int i = 0; i < childCount; i++) { 17510 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 17511 childInfo.sendPackageRemovedBroadcastInternal(killApp); 17512 } 17513 } 17514 17515 void sendSystemPackageUpdatedBroadcasts() { 17516 if (isRemovedPackageSystemUpdate) { 17517 sendSystemPackageUpdatedBroadcastsInternal(); 17518 final int childCount = (removedChildPackages != null) 17519 ? removedChildPackages.size() : 0; 17520 for (int i = 0; i < childCount; i++) { 17521 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 17522 if (childInfo.isRemovedPackageSystemUpdate) { 17523 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 17524 } 17525 } 17526 } 17527 } 17528 17529 void sendSystemPackageAppearedBroadcasts() { 17530 final int packageCount = (appearedChildPackages != null) 17531 ? appearedChildPackages.size() : 0; 17532 for (int i = 0; i < packageCount; i++) { 17533 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 17534 sendPackageAddedForNewUsers(installedInfo.name, true, 17535 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers); 17536 } 17537 } 17538 17539 private void sendSystemPackageUpdatedBroadcastsInternal() { 17540 Bundle extras = new Bundle(2); 17541 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 17542 extras.putBoolean(Intent.EXTRA_REPLACING, true); 17543 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 17544 extras, 0, null, null, null); 17545 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 17546 extras, 0, null, null, null); 17547 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 17548 null, 0, removedPackage, null, null); 17549 } 17550 17551 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 17552 // Don't send static shared library removal broadcasts as these 17553 // libs are visible only the the apps that depend on them an one 17554 // cannot remove the library if it has a dependency. 17555 if (isStaticSharedLib) { 17556 return; 17557 } 17558 Bundle extras = new Bundle(2); 17559 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 17560 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 17561 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 17562 if (isUpdate || isRemovedPackageSystemUpdate) { 17563 extras.putBoolean(Intent.EXTRA_REPLACING, true); 17564 } 17565 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 17566 if (removedPackage != null) { 17567 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 17568 extras, 0, null, null, removedUsers); 17569 if (dataRemoved && !isRemovedPackageSystemUpdate) { 17570 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 17571 removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, 17572 null, null, removedUsers); 17573 } 17574 } 17575 if (removedAppId >= 0) { 17576 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 17577 removedUsers); 17578 } 17579 } 17580 } 17581 17582 /* 17583 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 17584 * flag is not set, the data directory is removed as well. 17585 * make sure this flag is set for partially installed apps. If not its meaningless to 17586 * delete a partially installed application. 17587 */ 17588 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 17589 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 17590 String packageName = ps.name; 17591 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 17592 // Retrieve object to delete permissions for shared user later on 17593 final PackageParser.Package deletedPkg; 17594 final PackageSetting deletedPs; 17595 // reader 17596 synchronized (mPackages) { 17597 deletedPkg = mPackages.get(packageName); 17598 deletedPs = mSettings.mPackages.get(packageName); 17599 if (outInfo != null) { 17600 outInfo.removedPackage = packageName; 17601 outInfo.isStaticSharedLib = deletedPkg != null 17602 && deletedPkg.staticSharedLibName != null; 17603 outInfo.removedUsers = deletedPs != null 17604 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 17605 : null; 17606 } 17607 } 17608 17609 removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0); 17610 17611 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 17612 final PackageParser.Package resolvedPkg; 17613 if (deletedPkg != null) { 17614 resolvedPkg = deletedPkg; 17615 } else { 17616 // We don't have a parsed package when it lives on an ejected 17617 // adopted storage device, so fake something together 17618 resolvedPkg = new PackageParser.Package(ps.name); 17619 resolvedPkg.setVolumeUuid(ps.volumeUuid); 17620 } 17621 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 17622 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 17623 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 17624 if (outInfo != null) { 17625 outInfo.dataRemoved = true; 17626 } 17627 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 17628 } 17629 17630 int removedAppId = -1; 17631 17632 // writer 17633 synchronized (mPackages) { 17634 if (deletedPs != null) { 17635 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 17636 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 17637 clearDefaultBrowserIfNeeded(packageName); 17638 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 17639 removedAppId = mSettings.removePackageLPw(packageName); 17640 if (outInfo != null) { 17641 outInfo.removedAppId = removedAppId; 17642 } 17643 updatePermissionsLPw(deletedPs.name, null, 0); 17644 if (deletedPs.sharedUser != null) { 17645 // Remove permissions associated with package. Since runtime 17646 // permissions are per user we have to kill the removed package 17647 // or packages running under the shared user of the removed 17648 // package if revoking the permissions requested only by the removed 17649 // package is successful and this causes a change in gids. 17650 for (int userId : UserManagerService.getInstance().getUserIds()) { 17651 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 17652 userId); 17653 if (userIdToKill == UserHandle.USER_ALL 17654 || userIdToKill >= UserHandle.USER_SYSTEM) { 17655 // If gids changed for this user, kill all affected packages. 17656 mHandler.post(new Runnable() { 17657 @Override 17658 public void run() { 17659 // This has to happen with no lock held. 17660 killApplication(deletedPs.name, deletedPs.appId, 17661 KILL_APP_REASON_GIDS_CHANGED); 17662 } 17663 }); 17664 break; 17665 } 17666 } 17667 } 17668 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 17669 } 17670 // make sure to preserve per-user disabled state if this removal was just 17671 // a downgrade of a system app to the factory package 17672 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 17673 if (DEBUG_REMOVE) { 17674 Slog.d(TAG, "Propagating install state across downgrade"); 17675 } 17676 for (int userId : allUserHandles) { 17677 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 17678 if (DEBUG_REMOVE) { 17679 Slog.d(TAG, " user " + userId + " => " + installed); 17680 } 17681 ps.setInstalled(installed, userId); 17682 } 17683 } 17684 } 17685 // can downgrade to reader 17686 if (writeSettings) { 17687 // Save settings now 17688 mSettings.writeLPr(); 17689 } 17690 } 17691 if (removedAppId != -1) { 17692 // A user ID was deleted here. Go through all users and remove it 17693 // from KeyStore. 17694 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId); 17695 } 17696 } 17697 17698 static boolean locationIsPrivileged(File path) { 17699 try { 17700 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 17701 .getCanonicalPath(); 17702 return path.getCanonicalPath().startsWith(privilegedAppDir); 17703 } catch (IOException e) { 17704 Slog.e(TAG, "Unable to access code path " + path); 17705 } 17706 return false; 17707 } 17708 17709 /* 17710 * Tries to delete system package. 17711 */ 17712 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 17713 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 17714 boolean writeSettings) { 17715 if (deletedPs.parentPackageName != null) { 17716 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 17717 return false; 17718 } 17719 17720 final boolean applyUserRestrictions 17721 = (allUserHandles != null) && (outInfo.origUsers != null); 17722 final PackageSetting disabledPs; 17723 // Confirm if the system package has been updated 17724 // An updated system app can be deleted. This will also have to restore 17725 // the system pkg from system partition 17726 // reader 17727 synchronized (mPackages) { 17728 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 17729 } 17730 17731 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 17732 + " disabledPs=" + disabledPs); 17733 17734 if (disabledPs == null) { 17735 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 17736 return false; 17737 } else if (DEBUG_REMOVE) { 17738 Slog.d(TAG, "Deleting system pkg from data partition"); 17739 } 17740 17741 if (DEBUG_REMOVE) { 17742 if (applyUserRestrictions) { 17743 Slog.d(TAG, "Remembering install states:"); 17744 for (int userId : allUserHandles) { 17745 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 17746 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 17747 } 17748 } 17749 } 17750 17751 // Delete the updated package 17752 outInfo.isRemovedPackageSystemUpdate = true; 17753 if (outInfo.removedChildPackages != null) { 17754 final int childCount = (deletedPs.childPackageNames != null) 17755 ? deletedPs.childPackageNames.size() : 0; 17756 for (int i = 0; i < childCount; i++) { 17757 String childPackageName = deletedPs.childPackageNames.get(i); 17758 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 17759 .contains(childPackageName)) { 17760 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 17761 childPackageName); 17762 if (childInfo != null) { 17763 childInfo.isRemovedPackageSystemUpdate = true; 17764 } 17765 } 17766 } 17767 } 17768 17769 if (disabledPs.versionCode < deletedPs.versionCode) { 17770 // Delete data for downgrades 17771 flags &= ~PackageManager.DELETE_KEEP_DATA; 17772 } else { 17773 // Preserve data by setting flag 17774 flags |= PackageManager.DELETE_KEEP_DATA; 17775 } 17776 17777 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 17778 outInfo, writeSettings, disabledPs.pkg); 17779 if (!ret) { 17780 return false; 17781 } 17782 17783 // writer 17784 synchronized (mPackages) { 17785 // Reinstate the old system package 17786 enableSystemPackageLPw(disabledPs.pkg); 17787 // Remove any native libraries from the upgraded package. 17788 removeNativeBinariesLI(deletedPs); 17789 } 17790 17791 // Install the system package 17792 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 17793 int parseFlags = mDefParseFlags 17794 | PackageParser.PARSE_MUST_BE_APK 17795 | PackageParser.PARSE_IS_SYSTEM 17796 | PackageParser.PARSE_IS_SYSTEM_DIR; 17797 if (locationIsPrivileged(disabledPs.codePath)) { 17798 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 17799 } 17800 17801 final PackageParser.Package newPkg; 17802 try { 17803 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */, 17804 0 /* currentTime */, null); 17805 } catch (PackageManagerException e) { 17806 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 17807 + e.getMessage()); 17808 return false; 17809 } 17810 17811 try { 17812 // update shared libraries for the newly re-installed system package 17813 updateSharedLibrariesLPr(newPkg, null); 17814 } catch (PackageManagerException e) { 17815 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 17816 } 17817 17818 prepareAppDataAfterInstallLIF(newPkg); 17819 17820 // writer 17821 synchronized (mPackages) { 17822 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 17823 17824 // Propagate the permissions state as we do not want to drop on the floor 17825 // runtime permissions. The update permissions method below will take 17826 // care of removing obsolete permissions and grant install permissions. 17827 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 17828 updatePermissionsLPw(newPkg.packageName, newPkg, 17829 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 17830 17831 if (applyUserRestrictions) { 17832 if (DEBUG_REMOVE) { 17833 Slog.d(TAG, "Propagating install state across reinstall"); 17834 } 17835 for (int userId : allUserHandles) { 17836 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 17837 if (DEBUG_REMOVE) { 17838 Slog.d(TAG, " user " + userId + " => " + installed); 17839 } 17840 ps.setInstalled(installed, userId); 17841 17842 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17843 } 17844 // Regardless of writeSettings we need to ensure that this restriction 17845 // state propagation is persisted 17846 mSettings.writeAllUsersPackageRestrictionsLPr(); 17847 } 17848 // can downgrade to reader here 17849 if (writeSettings) { 17850 mSettings.writeLPr(); 17851 } 17852 } 17853 return true; 17854 } 17855 17856 private boolean deleteInstalledPackageLIF(PackageSetting ps, 17857 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 17858 PackageRemovedInfo outInfo, boolean writeSettings, 17859 PackageParser.Package replacingPackage) { 17860 synchronized (mPackages) { 17861 if (outInfo != null) { 17862 outInfo.uid = ps.appId; 17863 } 17864 17865 if (outInfo != null && outInfo.removedChildPackages != null) { 17866 final int childCount = (ps.childPackageNames != null) 17867 ? ps.childPackageNames.size() : 0; 17868 for (int i = 0; i < childCount; i++) { 17869 String childPackageName = ps.childPackageNames.get(i); 17870 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 17871 if (childPs == null) { 17872 return false; 17873 } 17874 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 17875 childPackageName); 17876 if (childInfo != null) { 17877 childInfo.uid = childPs.appId; 17878 } 17879 } 17880 } 17881 } 17882 17883 // Delete package data from internal structures and also remove data if flag is set 17884 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 17885 17886 // Delete the child packages data 17887 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 17888 for (int i = 0; i < childCount; i++) { 17889 PackageSetting childPs; 17890 synchronized (mPackages) { 17891 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 17892 } 17893 if (childPs != null) { 17894 PackageRemovedInfo childOutInfo = (outInfo != null 17895 && outInfo.removedChildPackages != null) 17896 ? outInfo.removedChildPackages.get(childPs.name) : null; 17897 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 17898 && (replacingPackage != null 17899 && !replacingPackage.hasChildPackage(childPs.name)) 17900 ? flags & ~DELETE_KEEP_DATA : flags; 17901 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 17902 deleteFlags, writeSettings); 17903 } 17904 } 17905 17906 // Delete application code and resources only for parent packages 17907 if (ps.parentPackageName == null) { 17908 if (deleteCodeAndResources && (outInfo != null)) { 17909 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 17910 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 17911 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 17912 } 17913 } 17914 17915 return true; 17916 } 17917 17918 @Override 17919 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 17920 int userId) { 17921 mContext.enforceCallingOrSelfPermission( 17922 android.Manifest.permission.DELETE_PACKAGES, null); 17923 synchronized (mPackages) { 17924 PackageSetting ps = mSettings.mPackages.get(packageName); 17925 if (ps == null) { 17926 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 17927 return false; 17928 } 17929 // Cannot block uninstall of static shared libs as they are 17930 // considered a part of the using app (emulating static linking). 17931 // Also static libs are installed always on internal storage. 17932 PackageParser.Package pkg = mPackages.get(packageName); 17933 if (pkg != null && pkg.staticSharedLibName != null) { 17934 Slog.w(TAG, "Cannot block uninstall of package: " + packageName 17935 + " providing static shared library: " + pkg.staticSharedLibName); 17936 return false; 17937 } 17938 if (!ps.getInstalled(userId)) { 17939 // Can't block uninstall for an app that is not installed or enabled. 17940 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 17941 return false; 17942 } 17943 ps.setBlockUninstall(blockUninstall, userId); 17944 mSettings.writePackageRestrictionsLPr(userId); 17945 } 17946 return true; 17947 } 17948 17949 @Override 17950 public boolean getBlockUninstallForUser(String packageName, int userId) { 17951 synchronized (mPackages) { 17952 PackageSetting ps = mSettings.mPackages.get(packageName); 17953 if (ps == null) { 17954 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 17955 return false; 17956 } 17957 return ps.getBlockUninstall(userId); 17958 } 17959 } 17960 17961 @Override 17962 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 17963 int callingUid = Binder.getCallingUid(); 17964 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 17965 throw new SecurityException( 17966 "setRequiredForSystemUser can only be run by the system or root"); 17967 } 17968 synchronized (mPackages) { 17969 PackageSetting ps = mSettings.mPackages.get(packageName); 17970 if (ps == null) { 17971 Log.w(TAG, "Package doesn't exist: " + packageName); 17972 return false; 17973 } 17974 if (systemUserApp) { 17975 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 17976 } else { 17977 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 17978 } 17979 mSettings.writeLPr(); 17980 } 17981 return true; 17982 } 17983 17984 /* 17985 * This method handles package deletion in general 17986 */ 17987 private boolean deletePackageLIF(String packageName, UserHandle user, 17988 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 17989 PackageRemovedInfo outInfo, boolean writeSettings, 17990 PackageParser.Package replacingPackage) { 17991 if (packageName == null) { 17992 Slog.w(TAG, "Attempt to delete null packageName."); 17993 return false; 17994 } 17995 17996 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 17997 17998 PackageSetting ps; 17999 synchronized (mPackages) { 18000 ps = mSettings.mPackages.get(packageName); 18001 if (ps == null) { 18002 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 18003 return false; 18004 } 18005 18006 if (ps.parentPackageName != null && (!isSystemApp(ps) 18007 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 18008 if (DEBUG_REMOVE) { 18009 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 18010 + ((user == null) ? UserHandle.USER_ALL : user)); 18011 } 18012 final int removedUserId = (user != null) ? user.getIdentifier() 18013 : UserHandle.USER_ALL; 18014 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 18015 return false; 18016 } 18017 markPackageUninstalledForUserLPw(ps, user); 18018 scheduleWritePackageRestrictionsLocked(user); 18019 return true; 18020 } 18021 } 18022 18023 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 18024 && user.getIdentifier() != UserHandle.USER_ALL)) { 18025 // The caller is asking that the package only be deleted for a single 18026 // user. To do this, we just mark its uninstalled state and delete 18027 // its data. If this is a system app, we only allow this to happen if 18028 // they have set the special DELETE_SYSTEM_APP which requests different 18029 // semantics than normal for uninstalling system apps. 18030 markPackageUninstalledForUserLPw(ps, user); 18031 18032 if (!isSystemApp(ps)) { 18033 // Do not uninstall the APK if an app should be cached 18034 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 18035 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 18036 // Other user still have this package installed, so all 18037 // we need to do is clear this user's data and save that 18038 // it is uninstalled. 18039 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 18040 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 18041 return false; 18042 } 18043 scheduleWritePackageRestrictionsLocked(user); 18044 return true; 18045 } else { 18046 // We need to set it back to 'installed' so the uninstall 18047 // broadcasts will be sent correctly. 18048 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 18049 ps.setInstalled(true, user.getIdentifier()); 18050 } 18051 } else { 18052 // This is a system app, so we assume that the 18053 // other users still have this package installed, so all 18054 // we need to do is clear this user's data and save that 18055 // it is uninstalled. 18056 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 18057 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 18058 return false; 18059 } 18060 scheduleWritePackageRestrictionsLocked(user); 18061 return true; 18062 } 18063 } 18064 18065 // If we are deleting a composite package for all users, keep track 18066 // of result for each child. 18067 if (ps.childPackageNames != null && outInfo != null) { 18068 synchronized (mPackages) { 18069 final int childCount = ps.childPackageNames.size(); 18070 outInfo.removedChildPackages = new ArrayMap<>(childCount); 18071 for (int i = 0; i < childCount; i++) { 18072 String childPackageName = ps.childPackageNames.get(i); 18073 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 18074 childInfo.removedPackage = childPackageName; 18075 outInfo.removedChildPackages.put(childPackageName, childInfo); 18076 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 18077 if (childPs != null) { 18078 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 18079 } 18080 } 18081 } 18082 } 18083 18084 boolean ret = false; 18085 if (isSystemApp(ps)) { 18086 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 18087 // When an updated system application is deleted we delete the existing resources 18088 // as well and fall back to existing code in system partition 18089 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 18090 } else { 18091 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 18092 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 18093 outInfo, writeSettings, replacingPackage); 18094 } 18095 18096 // Take a note whether we deleted the package for all users 18097 if (outInfo != null) { 18098 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 18099 if (outInfo.removedChildPackages != null) { 18100 synchronized (mPackages) { 18101 final int childCount = outInfo.removedChildPackages.size(); 18102 for (int i = 0; i < childCount; i++) { 18103 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 18104 if (childInfo != null) { 18105 childInfo.removedForAllUsers = mPackages.get( 18106 childInfo.removedPackage) == null; 18107 } 18108 } 18109 } 18110 } 18111 // If we uninstalled an update to a system app there may be some 18112 // child packages that appeared as they are declared in the system 18113 // app but were not declared in the update. 18114 if (isSystemApp(ps)) { 18115 synchronized (mPackages) { 18116 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name); 18117 final int childCount = (updatedPs.childPackageNames != null) 18118 ? updatedPs.childPackageNames.size() : 0; 18119 for (int i = 0; i < childCount; i++) { 18120 String childPackageName = updatedPs.childPackageNames.get(i); 18121 if (outInfo.removedChildPackages == null 18122 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 18123 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 18124 if (childPs == null) { 18125 continue; 18126 } 18127 PackageInstalledInfo installRes = new PackageInstalledInfo(); 18128 installRes.name = childPackageName; 18129 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 18130 installRes.pkg = mPackages.get(childPackageName); 18131 installRes.uid = childPs.pkg.applicationInfo.uid; 18132 if (outInfo.appearedChildPackages == null) { 18133 outInfo.appearedChildPackages = new ArrayMap<>(); 18134 } 18135 outInfo.appearedChildPackages.put(childPackageName, installRes); 18136 } 18137 } 18138 } 18139 } 18140 } 18141 18142 return ret; 18143 } 18144 18145 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 18146 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 18147 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 18148 for (int nextUserId : userIds) { 18149 if (DEBUG_REMOVE) { 18150 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 18151 } 18152 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 18153 false /*installed*/, 18154 true /*stopped*/, 18155 true /*notLaunched*/, 18156 false /*hidden*/, 18157 false /*suspended*/, 18158 false /*instantApp*/, 18159 null /*lastDisableAppCaller*/, 18160 null /*enabledComponents*/, 18161 null /*disabledComponents*/, 18162 false /*blockUninstall*/, 18163 ps.readUserState(nextUserId).domainVerificationStatus, 18164 0, PackageManager.INSTALL_REASON_UNKNOWN); 18165 } 18166 } 18167 18168 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 18169 PackageRemovedInfo outInfo) { 18170 final PackageParser.Package pkg; 18171 synchronized (mPackages) { 18172 pkg = mPackages.get(ps.name); 18173 } 18174 18175 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 18176 : new int[] {userId}; 18177 for (int nextUserId : userIds) { 18178 if (DEBUG_REMOVE) { 18179 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 18180 + nextUserId); 18181 } 18182 18183 destroyAppDataLIF(pkg, userId, 18184 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 18185 destroyAppProfilesLIF(pkg, userId); 18186 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 18187 schedulePackageCleaning(ps.name, nextUserId, false); 18188 synchronized (mPackages) { 18189 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 18190 scheduleWritePackageRestrictionsLocked(nextUserId); 18191 } 18192 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 18193 } 18194 } 18195 18196 if (outInfo != null) { 18197 outInfo.removedPackage = ps.name; 18198 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null; 18199 outInfo.removedAppId = ps.appId; 18200 outInfo.removedUsers = userIds; 18201 } 18202 18203 return true; 18204 } 18205 18206 private final class ClearStorageConnection implements ServiceConnection { 18207 IMediaContainerService mContainerService; 18208 18209 @Override 18210 public void onServiceConnected(ComponentName name, IBinder service) { 18211 synchronized (this) { 18212 mContainerService = IMediaContainerService.Stub 18213 .asInterface(Binder.allowBlocking(service)); 18214 notifyAll(); 18215 } 18216 } 18217 18218 @Override 18219 public void onServiceDisconnected(ComponentName name) { 18220 } 18221 } 18222 18223 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 18224 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 18225 18226 final boolean mounted; 18227 if (Environment.isExternalStorageEmulated()) { 18228 mounted = true; 18229 } else { 18230 final String status = Environment.getExternalStorageState(); 18231 18232 mounted = status.equals(Environment.MEDIA_MOUNTED) 18233 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 18234 } 18235 18236 if (!mounted) { 18237 return; 18238 } 18239 18240 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 18241 int[] users; 18242 if (userId == UserHandle.USER_ALL) { 18243 users = sUserManager.getUserIds(); 18244 } else { 18245 users = new int[] { userId }; 18246 } 18247 final ClearStorageConnection conn = new ClearStorageConnection(); 18248 if (mContext.bindServiceAsUser( 18249 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 18250 try { 18251 for (int curUser : users) { 18252 long timeout = SystemClock.uptimeMillis() + 5000; 18253 synchronized (conn) { 18254 long now; 18255 while (conn.mContainerService == null && 18256 (now = SystemClock.uptimeMillis()) < timeout) { 18257 try { 18258 conn.wait(timeout - now); 18259 } catch (InterruptedException e) { 18260 } 18261 } 18262 } 18263 if (conn.mContainerService == null) { 18264 return; 18265 } 18266 18267 final UserEnvironment userEnv = new UserEnvironment(curUser); 18268 clearDirectory(conn.mContainerService, 18269 userEnv.buildExternalStorageAppCacheDirs(packageName)); 18270 if (allData) { 18271 clearDirectory(conn.mContainerService, 18272 userEnv.buildExternalStorageAppDataDirs(packageName)); 18273 clearDirectory(conn.mContainerService, 18274 userEnv.buildExternalStorageAppMediaDirs(packageName)); 18275 } 18276 } 18277 } finally { 18278 mContext.unbindService(conn); 18279 } 18280 } 18281 } 18282 18283 @Override 18284 public void clearApplicationProfileData(String packageName) { 18285 enforceSystemOrRoot("Only the system can clear all profile data"); 18286 18287 final PackageParser.Package pkg; 18288 synchronized (mPackages) { 18289 pkg = mPackages.get(packageName); 18290 } 18291 18292 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 18293 synchronized (mInstallLock) { 18294 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 18295 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL, 18296 true /* removeBaseMarker */); 18297 } 18298 } 18299 } 18300 18301 @Override 18302 public void clearApplicationUserData(final String packageName, 18303 final IPackageDataObserver observer, final int userId) { 18304 mContext.enforceCallingOrSelfPermission( 18305 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 18306 18307 enforceCrossUserPermission(Binder.getCallingUid(), userId, 18308 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 18309 18310 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 18311 throw new SecurityException("Cannot clear data for a protected package: " 18312 + packageName); 18313 } 18314 // Queue up an async operation since the package deletion may take a little while. 18315 mHandler.post(new Runnable() { 18316 public void run() { 18317 mHandler.removeCallbacks(this); 18318 final boolean succeeded; 18319 try (PackageFreezer freezer = freezePackage(packageName, 18320 "clearApplicationUserData")) { 18321 synchronized (mInstallLock) { 18322 succeeded = clearApplicationUserDataLIF(packageName, userId); 18323 } 18324 clearExternalStorageDataSync(packageName, userId, true); 18325 synchronized (mPackages) { 18326 mInstantAppRegistry.deleteInstantApplicationMetadataLPw( 18327 packageName, userId); 18328 } 18329 } 18330 if (succeeded) { 18331 // invoke DeviceStorageMonitor's update method to clear any notifications 18332 DeviceStorageMonitorInternal dsm = LocalServices 18333 .getService(DeviceStorageMonitorInternal.class); 18334 if (dsm != null) { 18335 dsm.checkMemory(); 18336 } 18337 } 18338 if(observer != null) { 18339 try { 18340 observer.onRemoveCompleted(packageName, succeeded); 18341 } catch (RemoteException e) { 18342 Log.i(TAG, "Observer no longer exists."); 18343 } 18344 } //end if observer 18345 } //end run 18346 }); 18347 } 18348 18349 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 18350 if (packageName == null) { 18351 Slog.w(TAG, "Attempt to delete null packageName."); 18352 return false; 18353 } 18354 18355 // Try finding details about the requested package 18356 PackageParser.Package pkg; 18357 synchronized (mPackages) { 18358 pkg = mPackages.get(packageName); 18359 if (pkg == null) { 18360 final PackageSetting ps = mSettings.mPackages.get(packageName); 18361 if (ps != null) { 18362 pkg = ps.pkg; 18363 } 18364 } 18365 18366 if (pkg == null) { 18367 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 18368 return false; 18369 } 18370 18371 PackageSetting ps = (PackageSetting) pkg.mExtras; 18372 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 18373 } 18374 18375 clearAppDataLIF(pkg, userId, 18376 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 18377 18378 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18379 removeKeystoreDataIfNeeded(userId, appId); 18380 18381 UserManagerInternal umInternal = getUserManagerInternal(); 18382 final int flags; 18383 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 18384 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18385 } else if (umInternal.isUserRunning(userId)) { 18386 flags = StorageManager.FLAG_STORAGE_DE; 18387 } else { 18388 flags = 0; 18389 } 18390 prepareAppDataContentsLIF(pkg, userId, flags); 18391 18392 return true; 18393 } 18394 18395 /** 18396 * Reverts user permission state changes (permissions and flags) in 18397 * all packages for a given user. 18398 * 18399 * @param userId The device user for which to do a reset. 18400 */ 18401 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 18402 final int packageCount = mPackages.size(); 18403 for (int i = 0; i < packageCount; i++) { 18404 PackageParser.Package pkg = mPackages.valueAt(i); 18405 PackageSetting ps = (PackageSetting) pkg.mExtras; 18406 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 18407 } 18408 } 18409 18410 private void resetNetworkPolicies(int userId) { 18411 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 18412 } 18413 18414 /** 18415 * Reverts user permission state changes (permissions and flags). 18416 * 18417 * @param ps The package for which to reset. 18418 * @param userId The device user for which to do a reset. 18419 */ 18420 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 18421 final PackageSetting ps, final int userId) { 18422 if (ps.pkg == null) { 18423 return; 18424 } 18425 18426 // These are flags that can change base on user actions. 18427 final int userSettableMask = FLAG_PERMISSION_USER_SET 18428 | FLAG_PERMISSION_USER_FIXED 18429 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 18430 | FLAG_PERMISSION_REVIEW_REQUIRED; 18431 18432 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 18433 | FLAG_PERMISSION_POLICY_FIXED; 18434 18435 boolean writeInstallPermissions = false; 18436 boolean writeRuntimePermissions = false; 18437 18438 final int permissionCount = ps.pkg.requestedPermissions.size(); 18439 for (int i = 0; i < permissionCount; i++) { 18440 String permission = ps.pkg.requestedPermissions.get(i); 18441 18442 BasePermission bp = mSettings.mPermissions.get(permission); 18443 if (bp == null) { 18444 continue; 18445 } 18446 18447 // If shared user we just reset the state to which only this app contributed. 18448 if (ps.sharedUser != null) { 18449 boolean used = false; 18450 final int packageCount = ps.sharedUser.packages.size(); 18451 for (int j = 0; j < packageCount; j++) { 18452 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 18453 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 18454 && pkg.pkg.requestedPermissions.contains(permission)) { 18455 used = true; 18456 break; 18457 } 18458 } 18459 if (used) { 18460 continue; 18461 } 18462 } 18463 18464 PermissionsState permissionsState = ps.getPermissionsState(); 18465 18466 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 18467 18468 // Always clear the user settable flags. 18469 final boolean hasInstallState = permissionsState.getInstallPermissionState( 18470 bp.name) != null; 18471 // If permission review is enabled and this is a legacy app, mark the 18472 // permission as requiring a review as this is the initial state. 18473 int flags = 0; 18474 if (mPermissionReviewRequired 18475 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 18476 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 18477 } 18478 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 18479 if (hasInstallState) { 18480 writeInstallPermissions = true; 18481 } else { 18482 writeRuntimePermissions = true; 18483 } 18484 } 18485 18486 // Below is only runtime permission handling. 18487 if (!bp.isRuntime()) { 18488 continue; 18489 } 18490 18491 // Never clobber system or policy. 18492 if ((oldFlags & policyOrSystemFlags) != 0) { 18493 continue; 18494 } 18495 18496 // If this permission was granted by default, make sure it is. 18497 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 18498 if (permissionsState.grantRuntimePermission(bp, userId) 18499 != PERMISSION_OPERATION_FAILURE) { 18500 writeRuntimePermissions = true; 18501 } 18502 // If permission review is enabled the permissions for a legacy apps 18503 // are represented as constantly granted runtime ones, so don't revoke. 18504 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 18505 // Otherwise, reset the permission. 18506 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 18507 switch (revokeResult) { 18508 case PERMISSION_OPERATION_SUCCESS: 18509 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 18510 writeRuntimePermissions = true; 18511 final int appId = ps.appId; 18512 mHandler.post(new Runnable() { 18513 @Override 18514 public void run() { 18515 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 18516 } 18517 }); 18518 } break; 18519 } 18520 } 18521 } 18522 18523 // Synchronously write as we are taking permissions away. 18524 if (writeRuntimePermissions) { 18525 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 18526 } 18527 18528 // Synchronously write as we are taking permissions away. 18529 if (writeInstallPermissions) { 18530 mSettings.writeLPr(); 18531 } 18532 } 18533 18534 /** 18535 * Remove entries from the keystore daemon. Will only remove it if the 18536 * {@code appId} is valid. 18537 */ 18538 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 18539 if (appId < 0) { 18540 return; 18541 } 18542 18543 final KeyStore keyStore = KeyStore.getInstance(); 18544 if (keyStore != null) { 18545 if (userId == UserHandle.USER_ALL) { 18546 for (final int individual : sUserManager.getUserIds()) { 18547 keyStore.clearUid(UserHandle.getUid(individual, appId)); 18548 } 18549 } else { 18550 keyStore.clearUid(UserHandle.getUid(userId, appId)); 18551 } 18552 } else { 18553 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 18554 } 18555 } 18556 18557 @Override 18558 public void deleteApplicationCacheFiles(final String packageName, 18559 final IPackageDataObserver observer) { 18560 final int userId = UserHandle.getCallingUserId(); 18561 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 18562 } 18563 18564 @Override 18565 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 18566 final IPackageDataObserver observer) { 18567 mContext.enforceCallingOrSelfPermission( 18568 android.Manifest.permission.DELETE_CACHE_FILES, null); 18569 enforceCrossUserPermission(Binder.getCallingUid(), userId, 18570 /* requireFullPermission= */ true, /* checkShell= */ false, 18571 "delete application cache files"); 18572 18573 final PackageParser.Package pkg; 18574 synchronized (mPackages) { 18575 pkg = mPackages.get(packageName); 18576 } 18577 18578 // Queue up an async operation since the package deletion may take a little while. 18579 mHandler.post(new Runnable() { 18580 public void run() { 18581 synchronized (mInstallLock) { 18582 final int flags = StorageManager.FLAG_STORAGE_DE 18583 | StorageManager.FLAG_STORAGE_CE; 18584 // We're only clearing cache files, so we don't care if the 18585 // app is unfrozen and still able to run 18586 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 18587 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 18588 } 18589 clearExternalStorageDataSync(packageName, userId, false); 18590 if (observer != null) { 18591 try { 18592 observer.onRemoveCompleted(packageName, true); 18593 } catch (RemoteException e) { 18594 Log.i(TAG, "Observer no longer exists."); 18595 } 18596 } 18597 } 18598 }); 18599 } 18600 18601 @Override 18602 public void getPackageSizeInfo(final String packageName, int userHandle, 18603 final IPackageStatsObserver observer) { 18604 mContext.enforceCallingOrSelfPermission( 18605 android.Manifest.permission.GET_PACKAGE_SIZE, null); 18606 if (packageName == null) { 18607 throw new IllegalArgumentException("Attempt to get size of null packageName"); 18608 } 18609 18610 PackageStats stats = new PackageStats(packageName, userHandle); 18611 18612 /* 18613 * Queue up an async operation since the package measurement may take a 18614 * little while. 18615 */ 18616 Message msg = mHandler.obtainMessage(INIT_COPY); 18617 msg.obj = new MeasureParams(stats, observer); 18618 mHandler.sendMessage(msg); 18619 } 18620 18621 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 18622 final PackageSetting ps; 18623 synchronized (mPackages) { 18624 ps = mSettings.mPackages.get(packageName); 18625 if (ps == null) { 18626 Slog.w(TAG, "Failed to find settings for " + packageName); 18627 return false; 18628 } 18629 } 18630 18631 final String[] packageNames = { packageName }; 18632 final long[] ceDataInodes = { ps.getCeDataInode(userId) }; 18633 final String[] codePaths = { ps.codePathString }; 18634 18635 try { 18636 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0, 18637 ps.appId, ceDataInodes, codePaths, stats); 18638 18639 // For now, ignore code size of packages on system partition 18640 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 18641 stats.codeSize = 0; 18642 } 18643 18644 // External clients expect these to be tracked separately 18645 stats.dataSize -= stats.cacheSize; 18646 18647 } catch (InstallerException e) { 18648 Slog.w(TAG, String.valueOf(e)); 18649 return false; 18650 } 18651 18652 return true; 18653 } 18654 18655 private int getUidTargetSdkVersionLockedLPr(int uid) { 18656 Object obj = mSettings.getUserIdLPr(uid); 18657 if (obj instanceof SharedUserSetting) { 18658 final SharedUserSetting sus = (SharedUserSetting) obj; 18659 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 18660 final Iterator<PackageSetting> it = sus.packages.iterator(); 18661 while (it.hasNext()) { 18662 final PackageSetting ps = it.next(); 18663 if (ps.pkg != null) { 18664 int v = ps.pkg.applicationInfo.targetSdkVersion; 18665 if (v < vers) vers = v; 18666 } 18667 } 18668 return vers; 18669 } else if (obj instanceof PackageSetting) { 18670 final PackageSetting ps = (PackageSetting) obj; 18671 if (ps.pkg != null) { 18672 return ps.pkg.applicationInfo.targetSdkVersion; 18673 } 18674 } 18675 return Build.VERSION_CODES.CUR_DEVELOPMENT; 18676 } 18677 18678 @Override 18679 public void addPreferredActivity(IntentFilter filter, int match, 18680 ComponentName[] set, ComponentName activity, int userId) { 18681 addPreferredActivityInternal(filter, match, set, activity, true, userId, 18682 "Adding preferred"); 18683 } 18684 18685 private void addPreferredActivityInternal(IntentFilter filter, int match, 18686 ComponentName[] set, ComponentName activity, boolean always, int userId, 18687 String opname) { 18688 // writer 18689 int callingUid = Binder.getCallingUid(); 18690 enforceCrossUserPermission(callingUid, userId, 18691 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 18692 if (filter.countActions() == 0) { 18693 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 18694 return; 18695 } 18696 synchronized (mPackages) { 18697 if (mContext.checkCallingOrSelfPermission( 18698 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18699 != PackageManager.PERMISSION_GRANTED) { 18700 if (getUidTargetSdkVersionLockedLPr(callingUid) 18701 < Build.VERSION_CODES.FROYO) { 18702 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 18703 + callingUid); 18704 return; 18705 } 18706 mContext.enforceCallingOrSelfPermission( 18707 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18708 } 18709 18710 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 18711 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 18712 + userId + ":"); 18713 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18714 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 18715 scheduleWritePackageRestrictionsLocked(userId); 18716 postPreferredActivityChangedBroadcast(userId); 18717 } 18718 } 18719 18720 private void postPreferredActivityChangedBroadcast(int userId) { 18721 mHandler.post(() -> { 18722 final IActivityManager am = ActivityManager.getService(); 18723 if (am == null) { 18724 return; 18725 } 18726 18727 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 18728 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18729 try { 18730 am.broadcastIntent(null, intent, null, null, 18731 0, null, null, null, android.app.AppOpsManager.OP_NONE, 18732 null, false, false, userId); 18733 } catch (RemoteException e) { 18734 } 18735 }); 18736 } 18737 18738 @Override 18739 public void replacePreferredActivity(IntentFilter filter, int match, 18740 ComponentName[] set, ComponentName activity, int userId) { 18741 if (filter.countActions() != 1) { 18742 throw new IllegalArgumentException( 18743 "replacePreferredActivity expects filter to have only 1 action."); 18744 } 18745 if (filter.countDataAuthorities() != 0 18746 || filter.countDataPaths() != 0 18747 || filter.countDataSchemes() > 1 18748 || filter.countDataTypes() != 0) { 18749 throw new IllegalArgumentException( 18750 "replacePreferredActivity expects filter to have no data authorities, " + 18751 "paths, or types; and at most one scheme."); 18752 } 18753 18754 final int callingUid = Binder.getCallingUid(); 18755 enforceCrossUserPermission(callingUid, userId, 18756 true /* requireFullPermission */, false /* checkShell */, 18757 "replace preferred activity"); 18758 synchronized (mPackages) { 18759 if (mContext.checkCallingOrSelfPermission( 18760 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18761 != PackageManager.PERMISSION_GRANTED) { 18762 if (getUidTargetSdkVersionLockedLPr(callingUid) 18763 < Build.VERSION_CODES.FROYO) { 18764 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 18765 + Binder.getCallingUid()); 18766 return; 18767 } 18768 mContext.enforceCallingOrSelfPermission( 18769 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18770 } 18771 18772 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 18773 if (pir != null) { 18774 // Get all of the existing entries that exactly match this filter. 18775 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 18776 if (existing != null && existing.size() == 1) { 18777 PreferredActivity cur = existing.get(0); 18778 if (DEBUG_PREFERRED) { 18779 Slog.i(TAG, "Checking replace of preferred:"); 18780 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18781 if (!cur.mPref.mAlways) { 18782 Slog.i(TAG, " -- CUR; not mAlways!"); 18783 } else { 18784 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 18785 Slog.i(TAG, " -- CUR: mSet=" 18786 + Arrays.toString(cur.mPref.mSetComponents)); 18787 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 18788 Slog.i(TAG, " -- NEW: mMatch=" 18789 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 18790 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 18791 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 18792 } 18793 } 18794 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 18795 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 18796 && cur.mPref.sameSet(set)) { 18797 // Setting the preferred activity to what it happens to be already 18798 if (DEBUG_PREFERRED) { 18799 Slog.i(TAG, "Replacing with same preferred activity " 18800 + cur.mPref.mShortComponent + " for user " 18801 + userId + ":"); 18802 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18803 } 18804 return; 18805 } 18806 } 18807 18808 if (existing != null) { 18809 if (DEBUG_PREFERRED) { 18810 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 18811 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18812 } 18813 for (int i = 0; i < existing.size(); i++) { 18814 PreferredActivity pa = existing.get(i); 18815 if (DEBUG_PREFERRED) { 18816 Slog.i(TAG, "Removing existing preferred activity " 18817 + pa.mPref.mComponent + ":"); 18818 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 18819 } 18820 pir.removeFilter(pa); 18821 } 18822 } 18823 } 18824 addPreferredActivityInternal(filter, match, set, activity, true, userId, 18825 "Replacing preferred"); 18826 } 18827 } 18828 18829 @Override 18830 public void clearPackagePreferredActivities(String packageName) { 18831 final int uid = Binder.getCallingUid(); 18832 // writer 18833 synchronized (mPackages) { 18834 PackageParser.Package pkg = mPackages.get(packageName); 18835 if (pkg == null || pkg.applicationInfo.uid != uid) { 18836 if (mContext.checkCallingOrSelfPermission( 18837 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18838 != PackageManager.PERMISSION_GRANTED) { 18839 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 18840 < Build.VERSION_CODES.FROYO) { 18841 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 18842 + Binder.getCallingUid()); 18843 return; 18844 } 18845 mContext.enforceCallingOrSelfPermission( 18846 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18847 } 18848 } 18849 18850 int user = UserHandle.getCallingUserId(); 18851 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 18852 scheduleWritePackageRestrictionsLocked(user); 18853 } 18854 } 18855 } 18856 18857 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18858 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 18859 ArrayList<PreferredActivity> removed = null; 18860 boolean changed = false; 18861 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18862 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 18863 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18864 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 18865 continue; 18866 } 18867 Iterator<PreferredActivity> it = pir.filterIterator(); 18868 while (it.hasNext()) { 18869 PreferredActivity pa = it.next(); 18870 // Mark entry for removal only if it matches the package name 18871 // and the entry is of type "always". 18872 if (packageName == null || 18873 (pa.mPref.mComponent.getPackageName().equals(packageName) 18874 && pa.mPref.mAlways)) { 18875 if (removed == null) { 18876 removed = new ArrayList<PreferredActivity>(); 18877 } 18878 removed.add(pa); 18879 } 18880 } 18881 if (removed != null) { 18882 for (int j=0; j<removed.size(); j++) { 18883 PreferredActivity pa = removed.get(j); 18884 pir.removeFilter(pa); 18885 } 18886 changed = true; 18887 } 18888 } 18889 if (changed) { 18890 postPreferredActivityChangedBroadcast(userId); 18891 } 18892 return changed; 18893 } 18894 18895 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18896 private void clearIntentFilterVerificationsLPw(int userId) { 18897 final int packageCount = mPackages.size(); 18898 for (int i = 0; i < packageCount; i++) { 18899 PackageParser.Package pkg = mPackages.valueAt(i); 18900 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 18901 } 18902 } 18903 18904 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18905 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 18906 if (userId == UserHandle.USER_ALL) { 18907 if (mSettings.removeIntentFilterVerificationLPw(packageName, 18908 sUserManager.getUserIds())) { 18909 for (int oneUserId : sUserManager.getUserIds()) { 18910 scheduleWritePackageRestrictionsLocked(oneUserId); 18911 } 18912 } 18913 } else { 18914 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 18915 scheduleWritePackageRestrictionsLocked(userId); 18916 } 18917 } 18918 } 18919 18920 void clearDefaultBrowserIfNeeded(String packageName) { 18921 for (int oneUserId : sUserManager.getUserIds()) { 18922 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 18923 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 18924 if (packageName.equals(defaultBrowserPackageName)) { 18925 setDefaultBrowserPackageName(null, oneUserId); 18926 } 18927 } 18928 } 18929 18930 @Override 18931 public void resetApplicationPreferences(int userId) { 18932 mContext.enforceCallingOrSelfPermission( 18933 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18934 final long identity = Binder.clearCallingIdentity(); 18935 // writer 18936 try { 18937 synchronized (mPackages) { 18938 clearPackagePreferredActivitiesLPw(null, userId); 18939 mSettings.applyDefaultPreferredAppsLPw(this, userId); 18940 // TODO: We have to reset the default SMS and Phone. This requires 18941 // significant refactoring to keep all default apps in the package 18942 // manager (cleaner but more work) or have the services provide 18943 // callbacks to the package manager to request a default app reset. 18944 applyFactoryDefaultBrowserLPw(userId); 18945 clearIntentFilterVerificationsLPw(userId); 18946 primeDomainVerificationsLPw(userId); 18947 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 18948 scheduleWritePackageRestrictionsLocked(userId); 18949 } 18950 resetNetworkPolicies(userId); 18951 } finally { 18952 Binder.restoreCallingIdentity(identity); 18953 } 18954 } 18955 18956 @Override 18957 public int getPreferredActivities(List<IntentFilter> outFilters, 18958 List<ComponentName> outActivities, String packageName) { 18959 18960 int num = 0; 18961 final int userId = UserHandle.getCallingUserId(); 18962 // reader 18963 synchronized (mPackages) { 18964 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 18965 if (pir != null) { 18966 final Iterator<PreferredActivity> it = pir.filterIterator(); 18967 while (it.hasNext()) { 18968 final PreferredActivity pa = it.next(); 18969 if (packageName == null 18970 || (pa.mPref.mComponent.getPackageName().equals(packageName) 18971 && pa.mPref.mAlways)) { 18972 if (outFilters != null) { 18973 outFilters.add(new IntentFilter(pa)); 18974 } 18975 if (outActivities != null) { 18976 outActivities.add(pa.mPref.mComponent); 18977 } 18978 } 18979 } 18980 } 18981 } 18982 18983 return num; 18984 } 18985 18986 @Override 18987 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 18988 int userId) { 18989 int callingUid = Binder.getCallingUid(); 18990 if (callingUid != Process.SYSTEM_UID) { 18991 throw new SecurityException( 18992 "addPersistentPreferredActivity can only be run by the system"); 18993 } 18994 if (filter.countActions() == 0) { 18995 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 18996 return; 18997 } 18998 synchronized (mPackages) { 18999 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 19000 ":"); 19001 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 19002 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 19003 new PersistentPreferredActivity(filter, activity)); 19004 scheduleWritePackageRestrictionsLocked(userId); 19005 postPreferredActivityChangedBroadcast(userId); 19006 } 19007 } 19008 19009 @Override 19010 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 19011 int callingUid = Binder.getCallingUid(); 19012 if (callingUid != Process.SYSTEM_UID) { 19013 throw new SecurityException( 19014 "clearPackagePersistentPreferredActivities can only be run by the system"); 19015 } 19016 ArrayList<PersistentPreferredActivity> removed = null; 19017 boolean changed = false; 19018 synchronized (mPackages) { 19019 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 19020 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 19021 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 19022 .valueAt(i); 19023 if (userId != thisUserId) { 19024 continue; 19025 } 19026 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 19027 while (it.hasNext()) { 19028 PersistentPreferredActivity ppa = it.next(); 19029 // Mark entry for removal only if it matches the package name. 19030 if (ppa.mComponent.getPackageName().equals(packageName)) { 19031 if (removed == null) { 19032 removed = new ArrayList<PersistentPreferredActivity>(); 19033 } 19034 removed.add(ppa); 19035 } 19036 } 19037 if (removed != null) { 19038 for (int j=0; j<removed.size(); j++) { 19039 PersistentPreferredActivity ppa = removed.get(j); 19040 ppir.removeFilter(ppa); 19041 } 19042 changed = true; 19043 } 19044 } 19045 19046 if (changed) { 19047 scheduleWritePackageRestrictionsLocked(userId); 19048 postPreferredActivityChangedBroadcast(userId); 19049 } 19050 } 19051 } 19052 19053 /** 19054 * Common machinery for picking apart a restored XML blob and passing 19055 * it to a caller-supplied functor to be applied to the running system. 19056 */ 19057 private void restoreFromXml(XmlPullParser parser, int userId, 19058 String expectedStartTag, BlobXmlRestorer functor) 19059 throws IOException, XmlPullParserException { 19060 int type; 19061 while ((type = parser.next()) != XmlPullParser.START_TAG 19062 && type != XmlPullParser.END_DOCUMENT) { 19063 } 19064 if (type != XmlPullParser.START_TAG) { 19065 // oops didn't find a start tag?! 19066 if (DEBUG_BACKUP) { 19067 Slog.e(TAG, "Didn't find start tag during restore"); 19068 } 19069 return; 19070 } 19071Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 19072 // this is supposed to be TAG_PREFERRED_BACKUP 19073 if (!expectedStartTag.equals(parser.getName())) { 19074 if (DEBUG_BACKUP) { 19075 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 19076 } 19077 return; 19078 } 19079 19080 // skip interfering stuff, then we're aligned with the backing implementation 19081 while ((type = parser.next()) == XmlPullParser.TEXT) { } 19082Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 19083 functor.apply(parser, userId); 19084 } 19085 19086 private interface BlobXmlRestorer { 19087 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 19088 } 19089 19090 /** 19091 * Non-Binder method, support for the backup/restore mechanism: write the 19092 * full set of preferred activities in its canonical XML format. Returns the 19093 * XML output as a byte array, or null if there is none. 19094 */ 19095 @Override 19096 public byte[] getPreferredActivityBackup(int userId) { 19097 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19098 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 19099 } 19100 19101 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19102 try { 19103 final XmlSerializer serializer = new FastXmlSerializer(); 19104 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19105 serializer.startDocument(null, true); 19106 serializer.startTag(null, TAG_PREFERRED_BACKUP); 19107 19108 synchronized (mPackages) { 19109 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 19110 } 19111 19112 serializer.endTag(null, TAG_PREFERRED_BACKUP); 19113 serializer.endDocument(); 19114 serializer.flush(); 19115 } catch (Exception e) { 19116 if (DEBUG_BACKUP) { 19117 Slog.e(TAG, "Unable to write preferred activities for backup", e); 19118 } 19119 return null; 19120 } 19121 19122 return dataStream.toByteArray(); 19123 } 19124 19125 @Override 19126 public void restorePreferredActivities(byte[] backup, int userId) { 19127 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19128 throw new SecurityException("Only the system may call restorePreferredActivities()"); 19129 } 19130 19131 try { 19132 final XmlPullParser parser = Xml.newPullParser(); 19133 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19134 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 19135 new BlobXmlRestorer() { 19136 @Override 19137 public void apply(XmlPullParser parser, int userId) 19138 throws XmlPullParserException, IOException { 19139 synchronized (mPackages) { 19140 mSettings.readPreferredActivitiesLPw(parser, userId); 19141 } 19142 } 19143 } ); 19144 } catch (Exception e) { 19145 if (DEBUG_BACKUP) { 19146 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19147 } 19148 } 19149 } 19150 19151 /** 19152 * Non-Binder method, support for the backup/restore mechanism: write the 19153 * default browser (etc) settings in its canonical XML format. Returns the default 19154 * browser XML representation as a byte array, or null if there is none. 19155 */ 19156 @Override 19157 public byte[] getDefaultAppsBackup(int userId) { 19158 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19159 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 19160 } 19161 19162 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19163 try { 19164 final XmlSerializer serializer = new FastXmlSerializer(); 19165 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19166 serializer.startDocument(null, true); 19167 serializer.startTag(null, TAG_DEFAULT_APPS); 19168 19169 synchronized (mPackages) { 19170 mSettings.writeDefaultAppsLPr(serializer, userId); 19171 } 19172 19173 serializer.endTag(null, TAG_DEFAULT_APPS); 19174 serializer.endDocument(); 19175 serializer.flush(); 19176 } catch (Exception e) { 19177 if (DEBUG_BACKUP) { 19178 Slog.e(TAG, "Unable to write default apps for backup", e); 19179 } 19180 return null; 19181 } 19182 19183 return dataStream.toByteArray(); 19184 } 19185 19186 @Override 19187 public void restoreDefaultApps(byte[] backup, int userId) { 19188 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19189 throw new SecurityException("Only the system may call restoreDefaultApps()"); 19190 } 19191 19192 try { 19193 final XmlPullParser parser = Xml.newPullParser(); 19194 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19195 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 19196 new BlobXmlRestorer() { 19197 @Override 19198 public void apply(XmlPullParser parser, int userId) 19199 throws XmlPullParserException, IOException { 19200 synchronized (mPackages) { 19201 mSettings.readDefaultAppsLPw(parser, userId); 19202 } 19203 } 19204 } ); 19205 } catch (Exception e) { 19206 if (DEBUG_BACKUP) { 19207 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 19208 } 19209 } 19210 } 19211 19212 @Override 19213 public byte[] getIntentFilterVerificationBackup(int userId) { 19214 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19215 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 19216 } 19217 19218 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19219 try { 19220 final XmlSerializer serializer = new FastXmlSerializer(); 19221 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19222 serializer.startDocument(null, true); 19223 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 19224 19225 synchronized (mPackages) { 19226 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 19227 } 19228 19229 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 19230 serializer.endDocument(); 19231 serializer.flush(); 19232 } catch (Exception e) { 19233 if (DEBUG_BACKUP) { 19234 Slog.e(TAG, "Unable to write default apps for backup", e); 19235 } 19236 return null; 19237 } 19238 19239 return dataStream.toByteArray(); 19240 } 19241 19242 @Override 19243 public void restoreIntentFilterVerification(byte[] backup, int userId) { 19244 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19245 throw new SecurityException("Only the system may call restorePreferredActivities()"); 19246 } 19247 19248 try { 19249 final XmlPullParser parser = Xml.newPullParser(); 19250 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19251 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 19252 new BlobXmlRestorer() { 19253 @Override 19254 public void apply(XmlPullParser parser, int userId) 19255 throws XmlPullParserException, IOException { 19256 synchronized (mPackages) { 19257 mSettings.readAllDomainVerificationsLPr(parser, userId); 19258 mSettings.writeLPr(); 19259 } 19260 } 19261 } ); 19262 } catch (Exception e) { 19263 if (DEBUG_BACKUP) { 19264 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19265 } 19266 } 19267 } 19268 19269 @Override 19270 public byte[] getPermissionGrantBackup(int userId) { 19271 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19272 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 19273 } 19274 19275 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19276 try { 19277 final XmlSerializer serializer = new FastXmlSerializer(); 19278 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19279 serializer.startDocument(null, true); 19280 serializer.startTag(null, TAG_PERMISSION_BACKUP); 19281 19282 synchronized (mPackages) { 19283 serializeRuntimePermissionGrantsLPr(serializer, userId); 19284 } 19285 19286 serializer.endTag(null, TAG_PERMISSION_BACKUP); 19287 serializer.endDocument(); 19288 serializer.flush(); 19289 } catch (Exception e) { 19290 if (DEBUG_BACKUP) { 19291 Slog.e(TAG, "Unable to write default apps for backup", e); 19292 } 19293 return null; 19294 } 19295 19296 return dataStream.toByteArray(); 19297 } 19298 19299 @Override 19300 public void restorePermissionGrants(byte[] backup, int userId) { 19301 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19302 throw new SecurityException("Only the system may call restorePermissionGrants()"); 19303 } 19304 19305 try { 19306 final XmlPullParser parser = Xml.newPullParser(); 19307 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19308 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 19309 new BlobXmlRestorer() { 19310 @Override 19311 public void apply(XmlPullParser parser, int userId) 19312 throws XmlPullParserException, IOException { 19313 synchronized (mPackages) { 19314 processRestoredPermissionGrantsLPr(parser, userId); 19315 } 19316 } 19317 } ); 19318 } catch (Exception e) { 19319 if (DEBUG_BACKUP) { 19320 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19321 } 19322 } 19323 } 19324 19325 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 19326 throws IOException { 19327 serializer.startTag(null, TAG_ALL_GRANTS); 19328 19329 final int N = mSettings.mPackages.size(); 19330 for (int i = 0; i < N; i++) { 19331 final PackageSetting ps = mSettings.mPackages.valueAt(i); 19332 boolean pkgGrantsKnown = false; 19333 19334 PermissionsState packagePerms = ps.getPermissionsState(); 19335 19336 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 19337 final int grantFlags = state.getFlags(); 19338 // only look at grants that are not system/policy fixed 19339 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 19340 final boolean isGranted = state.isGranted(); 19341 // And only back up the user-twiddled state bits 19342 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 19343 final String packageName = mSettings.mPackages.keyAt(i); 19344 if (!pkgGrantsKnown) { 19345 serializer.startTag(null, TAG_GRANT); 19346 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 19347 pkgGrantsKnown = true; 19348 } 19349 19350 final boolean userSet = 19351 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 19352 final boolean userFixed = 19353 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 19354 final boolean revoke = 19355 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 19356 19357 serializer.startTag(null, TAG_PERMISSION); 19358 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 19359 if (isGranted) { 19360 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 19361 } 19362 if (userSet) { 19363 serializer.attribute(null, ATTR_USER_SET, "true"); 19364 } 19365 if (userFixed) { 19366 serializer.attribute(null, ATTR_USER_FIXED, "true"); 19367 } 19368 if (revoke) { 19369 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 19370 } 19371 serializer.endTag(null, TAG_PERMISSION); 19372 } 19373 } 19374 } 19375 19376 if (pkgGrantsKnown) { 19377 serializer.endTag(null, TAG_GRANT); 19378 } 19379 } 19380 19381 serializer.endTag(null, TAG_ALL_GRANTS); 19382 } 19383 19384 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 19385 throws XmlPullParserException, IOException { 19386 String pkgName = null; 19387 int outerDepth = parser.getDepth(); 19388 int type; 19389 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 19390 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 19391 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 19392 continue; 19393 } 19394 19395 final String tagName = parser.getName(); 19396 if (tagName.equals(TAG_GRANT)) { 19397 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 19398 if (DEBUG_BACKUP) { 19399 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 19400 } 19401 } else if (tagName.equals(TAG_PERMISSION)) { 19402 19403 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 19404 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 19405 19406 int newFlagSet = 0; 19407 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 19408 newFlagSet |= FLAG_PERMISSION_USER_SET; 19409 } 19410 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 19411 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 19412 } 19413 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 19414 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 19415 } 19416 if (DEBUG_BACKUP) { 19417 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 19418 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 19419 } 19420 final PackageSetting ps = mSettings.mPackages.get(pkgName); 19421 if (ps != null) { 19422 // Already installed so we apply the grant immediately 19423 if (DEBUG_BACKUP) { 19424 Slog.v(TAG, " + already installed; applying"); 19425 } 19426 PermissionsState perms = ps.getPermissionsState(); 19427 BasePermission bp = mSettings.mPermissions.get(permName); 19428 if (bp != null) { 19429 if (isGranted) { 19430 perms.grantRuntimePermission(bp, userId); 19431 } 19432 if (newFlagSet != 0) { 19433 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 19434 } 19435 } 19436 } else { 19437 // Need to wait for post-restore install to apply the grant 19438 if (DEBUG_BACKUP) { 19439 Slog.v(TAG, " - not yet installed; saving for later"); 19440 } 19441 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 19442 isGranted, newFlagSet, userId); 19443 } 19444 } else { 19445 PackageManagerService.reportSettingsProblem(Log.WARN, 19446 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 19447 XmlUtils.skipCurrentTag(parser); 19448 } 19449 } 19450 19451 scheduleWriteSettingsLocked(); 19452 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 19453 } 19454 19455 @Override 19456 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 19457 int sourceUserId, int targetUserId, int flags) { 19458 mContext.enforceCallingOrSelfPermission( 19459 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 19460 int callingUid = Binder.getCallingUid(); 19461 enforceOwnerRights(ownerPackage, callingUid); 19462 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 19463 if (intentFilter.countActions() == 0) { 19464 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 19465 return; 19466 } 19467 synchronized (mPackages) { 19468 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 19469 ownerPackage, targetUserId, flags); 19470 CrossProfileIntentResolver resolver = 19471 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 19472 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 19473 // We have all those whose filter is equal. Now checking if the rest is equal as well. 19474 if (existing != null) { 19475 int size = existing.size(); 19476 for (int i = 0; i < size; i++) { 19477 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 19478 return; 19479 } 19480 } 19481 } 19482 resolver.addFilter(newFilter); 19483 scheduleWritePackageRestrictionsLocked(sourceUserId); 19484 } 19485 } 19486 19487 @Override 19488 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 19489 mContext.enforceCallingOrSelfPermission( 19490 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 19491 int callingUid = Binder.getCallingUid(); 19492 enforceOwnerRights(ownerPackage, callingUid); 19493 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 19494 synchronized (mPackages) { 19495 CrossProfileIntentResolver resolver = 19496 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 19497 ArraySet<CrossProfileIntentFilter> set = 19498 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 19499 for (CrossProfileIntentFilter filter : set) { 19500 if (filter.getOwnerPackage().equals(ownerPackage)) { 19501 resolver.removeFilter(filter); 19502 } 19503 } 19504 scheduleWritePackageRestrictionsLocked(sourceUserId); 19505 } 19506 } 19507 19508 // Enforcing that callingUid is owning pkg on userId 19509 private void enforceOwnerRights(String pkg, int callingUid) { 19510 // The system owns everything. 19511 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 19512 return; 19513 } 19514 int callingUserId = UserHandle.getUserId(callingUid); 19515 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 19516 if (pi == null) { 19517 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 19518 + callingUserId); 19519 } 19520 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 19521 throw new SecurityException("Calling uid " + callingUid 19522 + " does not own package " + pkg); 19523 } 19524 } 19525 19526 @Override 19527 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 19528 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 19529 } 19530 19531 private Intent getHomeIntent() { 19532 Intent intent = new Intent(Intent.ACTION_MAIN); 19533 intent.addCategory(Intent.CATEGORY_HOME); 19534 intent.addCategory(Intent.CATEGORY_DEFAULT); 19535 return intent; 19536 } 19537 19538 private IntentFilter getHomeFilter() { 19539 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 19540 filter.addCategory(Intent.CATEGORY_HOME); 19541 filter.addCategory(Intent.CATEGORY_DEFAULT); 19542 return filter; 19543 } 19544 19545 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 19546 int userId) { 19547 Intent intent = getHomeIntent(); 19548 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 19549 PackageManager.GET_META_DATA, userId); 19550 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 19551 true, false, false, userId); 19552 19553 allHomeCandidates.clear(); 19554 if (list != null) { 19555 for (ResolveInfo ri : list) { 19556 allHomeCandidates.add(ri); 19557 } 19558 } 19559 return (preferred == null || preferred.activityInfo == null) 19560 ? null 19561 : new ComponentName(preferred.activityInfo.packageName, 19562 preferred.activityInfo.name); 19563 } 19564 19565 @Override 19566 public void setHomeActivity(ComponentName comp, int userId) { 19567 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 19568 getHomeActivitiesAsUser(homeActivities, userId); 19569 19570 boolean found = false; 19571 19572 final int size = homeActivities.size(); 19573 final ComponentName[] set = new ComponentName[size]; 19574 for (int i = 0; i < size; i++) { 19575 final ResolveInfo candidate = homeActivities.get(i); 19576 final ActivityInfo info = candidate.activityInfo; 19577 final ComponentName activityName = new ComponentName(info.packageName, info.name); 19578 set[i] = activityName; 19579 if (!found && activityName.equals(comp)) { 19580 found = true; 19581 } 19582 } 19583 if (!found) { 19584 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 19585 + userId); 19586 } 19587 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 19588 set, comp, userId); 19589 } 19590 19591 private @Nullable String getSetupWizardPackageName() { 19592 final Intent intent = new Intent(Intent.ACTION_MAIN); 19593 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 19594 19595 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 19596 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 19597 | MATCH_DISABLED_COMPONENTS, 19598 UserHandle.myUserId()); 19599 if (matches.size() == 1) { 19600 return matches.get(0).getComponentInfo().packageName; 19601 } else { 19602 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 19603 + ": matches=" + matches); 19604 return null; 19605 } 19606 } 19607 19608 private @Nullable String getStorageManagerPackageName() { 19609 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); 19610 19611 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 19612 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 19613 | MATCH_DISABLED_COMPONENTS, 19614 UserHandle.myUserId()); 19615 if (matches.size() == 1) { 19616 return matches.get(0).getComponentInfo().packageName; 19617 } else { 19618 Slog.e(TAG, "There should probably be exactly one storage manager; found " 19619 + matches.size() + ": matches=" + matches); 19620 return null; 19621 } 19622 } 19623 19624 @Override 19625 public void setApplicationEnabledSetting(String appPackageName, 19626 int newState, int flags, int userId, String callingPackage) { 19627 if (!sUserManager.exists(userId)) return; 19628 if (callingPackage == null) { 19629 callingPackage = Integer.toString(Binder.getCallingUid()); 19630 } 19631 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 19632 } 19633 19634 @Override 19635 public void setComponentEnabledSetting(ComponentName componentName, 19636 int newState, int flags, int userId) { 19637 if (!sUserManager.exists(userId)) return; 19638 setEnabledSetting(componentName.getPackageName(), 19639 componentName.getClassName(), newState, flags, userId, null); 19640 } 19641 19642 private void setEnabledSetting(final String packageName, String className, int newState, 19643 final int flags, int userId, String callingPackage) { 19644 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 19645 || newState == COMPONENT_ENABLED_STATE_ENABLED 19646 || newState == COMPONENT_ENABLED_STATE_DISABLED 19647 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 19648 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 19649 throw new IllegalArgumentException("Invalid new component state: " 19650 + newState); 19651 } 19652 PackageSetting pkgSetting; 19653 final int uid = Binder.getCallingUid(); 19654 final int permission; 19655 if (uid == Process.SYSTEM_UID) { 19656 permission = PackageManager.PERMISSION_GRANTED; 19657 } else { 19658 permission = mContext.checkCallingOrSelfPermission( 19659 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 19660 } 19661 enforceCrossUserPermission(uid, userId, 19662 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 19663 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 19664 boolean sendNow = false; 19665 boolean isApp = (className == null); 19666 String componentName = isApp ? packageName : className; 19667 int packageUid = -1; 19668 ArrayList<String> components; 19669 19670 // writer 19671 synchronized (mPackages) { 19672 pkgSetting = mSettings.mPackages.get(packageName); 19673 if (pkgSetting == null) { 19674 if (className == null) { 19675 throw new IllegalArgumentException("Unknown package: " + packageName); 19676 } 19677 throw new IllegalArgumentException( 19678 "Unknown component: " + packageName + "/" + className); 19679 } 19680 } 19681 19682 // Limit who can change which apps 19683 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 19684 // Don't allow apps that don't have permission to modify other apps 19685 if (!allowedByPermission) { 19686 throw new SecurityException( 19687 "Permission Denial: attempt to change component state from pid=" 19688 + Binder.getCallingPid() 19689 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 19690 } 19691 // Don't allow changing protected packages. 19692 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 19693 throw new SecurityException("Cannot disable a protected package: " + packageName); 19694 } 19695 } 19696 19697 synchronized (mPackages) { 19698 if (uid == Process.SHELL_UID 19699 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { 19700 // Shell can only change whole packages between ENABLED and DISABLED_USER states 19701 // unless it is a test package. 19702 int oldState = pkgSetting.getEnabled(userId); 19703 if (className == null 19704 && 19705 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 19706 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 19707 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 19708 && 19709 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 19710 || newState == COMPONENT_ENABLED_STATE_DEFAULT 19711 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 19712 // ok 19713 } else { 19714 throw new SecurityException( 19715 "Shell cannot change component state for " + packageName + "/" 19716 + className + " to " + newState); 19717 } 19718 } 19719 if (className == null) { 19720 // We're dealing with an application/package level state change 19721 if (pkgSetting.getEnabled(userId) == newState) { 19722 // Nothing to do 19723 return; 19724 } 19725 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 19726 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 19727 // Don't care about who enables an app. 19728 callingPackage = null; 19729 } 19730 pkgSetting.setEnabled(newState, userId, callingPackage); 19731 // pkgSetting.pkg.mSetEnabled = newState; 19732 } else { 19733 // We're dealing with a component level state change 19734 // First, verify that this is a valid class name. 19735 PackageParser.Package pkg = pkgSetting.pkg; 19736 if (pkg == null || !pkg.hasComponentClassName(className)) { 19737 if (pkg != null && 19738 pkg.applicationInfo.targetSdkVersion >= 19739 Build.VERSION_CODES.JELLY_BEAN) { 19740 throw new IllegalArgumentException("Component class " + className 19741 + " does not exist in " + packageName); 19742 } else { 19743 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 19744 + className + " does not exist in " + packageName); 19745 } 19746 } 19747 switch (newState) { 19748 case COMPONENT_ENABLED_STATE_ENABLED: 19749 if (!pkgSetting.enableComponentLPw(className, userId)) { 19750 return; 19751 } 19752 break; 19753 case COMPONENT_ENABLED_STATE_DISABLED: 19754 if (!pkgSetting.disableComponentLPw(className, userId)) { 19755 return; 19756 } 19757 break; 19758 case COMPONENT_ENABLED_STATE_DEFAULT: 19759 if (!pkgSetting.restoreComponentLPw(className, userId)) { 19760 return; 19761 } 19762 break; 19763 default: 19764 Slog.e(TAG, "Invalid new component state: " + newState); 19765 return; 19766 } 19767 } 19768 scheduleWritePackageRestrictionsLocked(userId); 19769 components = mPendingBroadcasts.get(userId, packageName); 19770 final boolean newPackage = components == null; 19771 if (newPackage) { 19772 components = new ArrayList<String>(); 19773 } 19774 if (!components.contains(componentName)) { 19775 components.add(componentName); 19776 } 19777 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 19778 sendNow = true; 19779 // Purge entry from pending broadcast list if another one exists already 19780 // since we are sending one right away. 19781 mPendingBroadcasts.remove(userId, packageName); 19782 } else { 19783 if (newPackage) { 19784 mPendingBroadcasts.put(userId, packageName, components); 19785 } 19786 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 19787 // Schedule a message 19788 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 19789 } 19790 } 19791 } 19792 19793 long callingId = Binder.clearCallingIdentity(); 19794 try { 19795 if (sendNow) { 19796 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 19797 sendPackageChangedBroadcast(packageName, 19798 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 19799 } 19800 } finally { 19801 Binder.restoreCallingIdentity(callingId); 19802 } 19803 } 19804 19805 @Override 19806 public void flushPackageRestrictionsAsUser(int userId) { 19807 if (!sUserManager.exists(userId)) { 19808 return; 19809 } 19810 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 19811 false /* checkShell */, "flushPackageRestrictions"); 19812 synchronized (mPackages) { 19813 mSettings.writePackageRestrictionsLPr(userId); 19814 mDirtyUsers.remove(userId); 19815 if (mDirtyUsers.isEmpty()) { 19816 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 19817 } 19818 } 19819 } 19820 19821 private void sendPackageChangedBroadcast(String packageName, 19822 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 19823 if (DEBUG_INSTALL) 19824 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 19825 + componentNames); 19826 Bundle extras = new Bundle(4); 19827 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 19828 String nameList[] = new String[componentNames.size()]; 19829 componentNames.toArray(nameList); 19830 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 19831 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 19832 extras.putInt(Intent.EXTRA_UID, packageUid); 19833 // If this is not reporting a change of the overall package, then only send it 19834 // to registered receivers. We don't want to launch a swath of apps for every 19835 // little component state change. 19836 final int flags = !componentNames.contains(packageName) 19837 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 19838 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 19839 new int[] {UserHandle.getUserId(packageUid)}); 19840 } 19841 19842 @Override 19843 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 19844 if (!sUserManager.exists(userId)) return; 19845 final int uid = Binder.getCallingUid(); 19846 final int permission = mContext.checkCallingOrSelfPermission( 19847 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 19848 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 19849 enforceCrossUserPermission(uid, userId, 19850 true /* requireFullPermission */, true /* checkShell */, "stop package"); 19851 // writer 19852 synchronized (mPackages) { 19853 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 19854 allowedByPermission, uid, userId)) { 19855 scheduleWritePackageRestrictionsLocked(userId); 19856 } 19857 } 19858 } 19859 19860 @Override 19861 public String getInstallerPackageName(String packageName) { 19862 // reader 19863 synchronized (mPackages) { 19864 return mSettings.getInstallerPackageNameLPr(packageName); 19865 } 19866 } 19867 19868 public boolean isOrphaned(String packageName) { 19869 // reader 19870 synchronized (mPackages) { 19871 return mSettings.isOrphaned(packageName); 19872 } 19873 } 19874 19875 @Override 19876 public int getApplicationEnabledSetting(String packageName, int userId) { 19877 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 19878 int uid = Binder.getCallingUid(); 19879 enforceCrossUserPermission(uid, userId, 19880 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 19881 // reader 19882 synchronized (mPackages) { 19883 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 19884 } 19885 } 19886 19887 @Override 19888 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 19889 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 19890 int uid = Binder.getCallingUid(); 19891 enforceCrossUserPermission(uid, userId, 19892 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 19893 // reader 19894 synchronized (mPackages) { 19895 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 19896 } 19897 } 19898 19899 @Override 19900 public void enterSafeMode() { 19901 enforceSystemOrRoot("Only the system can request entering safe mode"); 19902 19903 if (!mSystemReady) { 19904 mSafeMode = true; 19905 } 19906 } 19907 19908 @Override 19909 public void systemReady() { 19910 mSystemReady = true; 19911 19912 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 19913 // disabled after already being started. 19914 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 19915 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 19916 19917 // Read the compatibilty setting when the system is ready. 19918 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 19919 mContext.getContentResolver(), 19920 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 19921 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 19922 if (DEBUG_SETTINGS) { 19923 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 19924 } 19925 19926 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 19927 19928 synchronized (mPackages) { 19929 // Verify that all of the preferred activity components actually 19930 // exist. It is possible for applications to be updated and at 19931 // that point remove a previously declared activity component that 19932 // had been set as a preferred activity. We try to clean this up 19933 // the next time we encounter that preferred activity, but it is 19934 // possible for the user flow to never be able to return to that 19935 // situation so here we do a sanity check to make sure we haven't 19936 // left any junk around. 19937 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 19938 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 19939 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 19940 removed.clear(); 19941 for (PreferredActivity pa : pir.filterSet()) { 19942 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 19943 removed.add(pa); 19944 } 19945 } 19946 if (removed.size() > 0) { 19947 for (int r=0; r<removed.size(); r++) { 19948 PreferredActivity pa = removed.get(r); 19949 Slog.w(TAG, "Removing dangling preferred activity: " 19950 + pa.mPref.mComponent); 19951 pir.removeFilter(pa); 19952 } 19953 mSettings.writePackageRestrictionsLPr( 19954 mSettings.mPreferredActivities.keyAt(i)); 19955 } 19956 } 19957 19958 for (int userId : UserManagerService.getInstance().getUserIds()) { 19959 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 19960 grantPermissionsUserIds = ArrayUtils.appendInt( 19961 grantPermissionsUserIds, userId); 19962 } 19963 } 19964 } 19965 sUserManager.systemReady(); 19966 19967 // If we upgraded grant all default permissions before kicking off. 19968 for (int userId : grantPermissionsUserIds) { 19969 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 19970 } 19971 19972 // If we did not grant default permissions, we preload from this the 19973 // default permission exceptions lazily to ensure we don't hit the 19974 // disk on a new user creation. 19975 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 19976 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 19977 } 19978 19979 // Kick off any messages waiting for system ready 19980 if (mPostSystemReadyMessages != null) { 19981 for (Message msg : mPostSystemReadyMessages) { 19982 msg.sendToTarget(); 19983 } 19984 mPostSystemReadyMessages = null; 19985 } 19986 19987 // Watch for external volumes that come and go over time 19988 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19989 storage.registerListener(mStorageListener); 19990 19991 mInstallerService.systemReady(); 19992 mPackageDexOptimizer.systemReady(); 19993 19994 StorageManagerInternal StorageManagerInternal = LocalServices.getService( 19995 StorageManagerInternal.class); 19996 StorageManagerInternal.addExternalStoragePolicy( 19997 new StorageManagerInternal.ExternalStorageMountPolicy() { 19998 @Override 19999 public int getMountMode(int uid, String packageName) { 20000 if (Process.isIsolated(uid)) { 20001 return Zygote.MOUNT_EXTERNAL_NONE; 20002 } 20003 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 20004 return Zygote.MOUNT_EXTERNAL_DEFAULT; 20005 } 20006 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 20007 return Zygote.MOUNT_EXTERNAL_DEFAULT; 20008 } 20009 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 20010 return Zygote.MOUNT_EXTERNAL_READ; 20011 } 20012 return Zygote.MOUNT_EXTERNAL_WRITE; 20013 } 20014 20015 @Override 20016 public boolean hasExternalStorage(int uid, String packageName) { 20017 return true; 20018 } 20019 }); 20020 20021 // Now that we're mostly running, clean up stale users and apps 20022 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 20023 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 20024 20025 if (mPrivappPermissionsViolations != null) { 20026 Slog.wtf(TAG,"Signature|privileged permissions not in " 20027 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations); 20028 mPrivappPermissionsViolations = null; 20029 } 20030 } 20031 20032 @Override 20033 public boolean isSafeMode() { 20034 return mSafeMode; 20035 } 20036 20037 @Override 20038 public boolean hasSystemUidErrors() { 20039 return mHasSystemUidErrors; 20040 } 20041 20042 static String arrayToString(int[] array) { 20043 StringBuffer buf = new StringBuffer(128); 20044 buf.append('['); 20045 if (array != null) { 20046 for (int i=0; i<array.length; i++) { 20047 if (i > 0) buf.append(", "); 20048 buf.append(array[i]); 20049 } 20050 } 20051 buf.append(']'); 20052 return buf.toString(); 20053 } 20054 20055 static class DumpState { 20056 public static final int DUMP_LIBS = 1 << 0; 20057 public static final int DUMP_FEATURES = 1 << 1; 20058 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 20059 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 20060 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 20061 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 20062 public static final int DUMP_PERMISSIONS = 1 << 6; 20063 public static final int DUMP_PACKAGES = 1 << 7; 20064 public static final int DUMP_SHARED_USERS = 1 << 8; 20065 public static final int DUMP_MESSAGES = 1 << 9; 20066 public static final int DUMP_PROVIDERS = 1 << 10; 20067 public static final int DUMP_VERIFIERS = 1 << 11; 20068 public static final int DUMP_PREFERRED = 1 << 12; 20069 public static final int DUMP_PREFERRED_XML = 1 << 13; 20070 public static final int DUMP_KEYSETS = 1 << 14; 20071 public static final int DUMP_VERSION = 1 << 15; 20072 public static final int DUMP_INSTALLS = 1 << 16; 20073 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 20074 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 20075 public static final int DUMP_FROZEN = 1 << 19; 20076 public static final int DUMP_DEXOPT = 1 << 20; 20077 public static final int DUMP_COMPILER_STATS = 1 << 21; 20078 20079 public static final int OPTION_SHOW_FILTERS = 1 << 0; 20080 20081 private int mTypes; 20082 20083 private int mOptions; 20084 20085 private boolean mTitlePrinted; 20086 20087 private SharedUserSetting mSharedUser; 20088 20089 public boolean isDumping(int type) { 20090 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 20091 return true; 20092 } 20093 20094 return (mTypes & type) != 0; 20095 } 20096 20097 public void setDump(int type) { 20098 mTypes |= type; 20099 } 20100 20101 public boolean isOptionEnabled(int option) { 20102 return (mOptions & option) != 0; 20103 } 20104 20105 public void setOptionEnabled(int option) { 20106 mOptions |= option; 20107 } 20108 20109 public boolean onTitlePrinted() { 20110 final boolean printed = mTitlePrinted; 20111 mTitlePrinted = true; 20112 return printed; 20113 } 20114 20115 public boolean getTitlePrinted() { 20116 return mTitlePrinted; 20117 } 20118 20119 public void setTitlePrinted(boolean enabled) { 20120 mTitlePrinted = enabled; 20121 } 20122 20123 public SharedUserSetting getSharedUser() { 20124 return mSharedUser; 20125 } 20126 20127 public void setSharedUser(SharedUserSetting user) { 20128 mSharedUser = user; 20129 } 20130 } 20131 20132 @Override 20133 public void onShellCommand(FileDescriptor in, FileDescriptor out, 20134 FileDescriptor err, String[] args, ShellCallback callback, 20135 ResultReceiver resultReceiver) { 20136 (new PackageManagerShellCommand(this)).exec( 20137 this, in, out, err, args, callback, resultReceiver); 20138 } 20139 20140 @Override 20141 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 20142 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 20143 != PackageManager.PERMISSION_GRANTED) { 20144 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 20145 + Binder.getCallingPid() 20146 + ", uid=" + Binder.getCallingUid() 20147 + " without permission " 20148 + android.Manifest.permission.DUMP); 20149 return; 20150 } 20151 20152 DumpState dumpState = new DumpState(); 20153 boolean fullPreferred = false; 20154 boolean checkin = false; 20155 20156 String packageName = null; 20157 ArraySet<String> permissionNames = null; 20158 20159 int opti = 0; 20160 while (opti < args.length) { 20161 String opt = args[opti]; 20162 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 20163 break; 20164 } 20165 opti++; 20166 20167 if ("-a".equals(opt)) { 20168 // Right now we only know how to print all. 20169 } else if ("-h".equals(opt)) { 20170 pw.println("Package manager dump options:"); 20171 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 20172 pw.println(" --checkin: dump for a checkin"); 20173 pw.println(" -f: print details of intent filters"); 20174 pw.println(" -h: print this help"); 20175 pw.println(" cmd may be one of:"); 20176 pw.println(" l[ibraries]: list known shared libraries"); 20177 pw.println(" f[eatures]: list device features"); 20178 pw.println(" k[eysets]: print known keysets"); 20179 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 20180 pw.println(" perm[issions]: dump permissions"); 20181 pw.println(" permission [name ...]: dump declaration and use of given permission"); 20182 pw.println(" pref[erred]: print preferred package settings"); 20183 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 20184 pw.println(" prov[iders]: dump content providers"); 20185 pw.println(" p[ackages]: dump installed packages"); 20186 pw.println(" s[hared-users]: dump shared user IDs"); 20187 pw.println(" m[essages]: print collected runtime messages"); 20188 pw.println(" v[erifiers]: print package verifier info"); 20189 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 20190 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 20191 pw.println(" version: print database version info"); 20192 pw.println(" write: write current settings now"); 20193 pw.println(" installs: details about install sessions"); 20194 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 20195 pw.println(" dexopt: dump dexopt state"); 20196 pw.println(" compiler-stats: dump compiler statistics"); 20197 pw.println(" <package.name>: info about given package"); 20198 return; 20199 } else if ("--checkin".equals(opt)) { 20200 checkin = true; 20201 } else if ("-f".equals(opt)) { 20202 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 20203 } else { 20204 pw.println("Unknown argument: " + opt + "; use -h for help"); 20205 } 20206 } 20207 20208 // Is the caller requesting to dump a particular piece of data? 20209 if (opti < args.length) { 20210 String cmd = args[opti]; 20211 opti++; 20212 // Is this a package name? 20213 if ("android".equals(cmd) || cmd.contains(".")) { 20214 packageName = cmd; 20215 // When dumping a single package, we always dump all of its 20216 // filter information since the amount of data will be reasonable. 20217 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 20218 } else if ("check-permission".equals(cmd)) { 20219 if (opti >= args.length) { 20220 pw.println("Error: check-permission missing permission argument"); 20221 return; 20222 } 20223 String perm = args[opti]; 20224 opti++; 20225 if (opti >= args.length) { 20226 pw.println("Error: check-permission missing package argument"); 20227 return; 20228 } 20229 20230 String pkg = args[opti]; 20231 opti++; 20232 int user = UserHandle.getUserId(Binder.getCallingUid()); 20233 if (opti < args.length) { 20234 try { 20235 user = Integer.parseInt(args[opti]); 20236 } catch (NumberFormatException e) { 20237 pw.println("Error: check-permission user argument is not a number: " 20238 + args[opti]); 20239 return; 20240 } 20241 } 20242 20243 // Normalize package name to handle renamed packages and static libs 20244 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST); 20245 20246 pw.println(checkPermission(perm, pkg, user)); 20247 return; 20248 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 20249 dumpState.setDump(DumpState.DUMP_LIBS); 20250 } else if ("f".equals(cmd) || "features".equals(cmd)) { 20251 dumpState.setDump(DumpState.DUMP_FEATURES); 20252 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 20253 if (opti >= args.length) { 20254 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 20255 | DumpState.DUMP_SERVICE_RESOLVERS 20256 | DumpState.DUMP_RECEIVER_RESOLVERS 20257 | DumpState.DUMP_CONTENT_RESOLVERS); 20258 } else { 20259 while (opti < args.length) { 20260 String name = args[opti]; 20261 if ("a".equals(name) || "activity".equals(name)) { 20262 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 20263 } else if ("s".equals(name) || "service".equals(name)) { 20264 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 20265 } else if ("r".equals(name) || "receiver".equals(name)) { 20266 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 20267 } else if ("c".equals(name) || "content".equals(name)) { 20268 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 20269 } else { 20270 pw.println("Error: unknown resolver table type: " + name); 20271 return; 20272 } 20273 opti++; 20274 } 20275 } 20276 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 20277 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 20278 } else if ("permission".equals(cmd)) { 20279 if (opti >= args.length) { 20280 pw.println("Error: permission requires permission name"); 20281 return; 20282 } 20283 permissionNames = new ArraySet<>(); 20284 while (opti < args.length) { 20285 permissionNames.add(args[opti]); 20286 opti++; 20287 } 20288 dumpState.setDump(DumpState.DUMP_PERMISSIONS 20289 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 20290 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 20291 dumpState.setDump(DumpState.DUMP_PREFERRED); 20292 } else if ("preferred-xml".equals(cmd)) { 20293 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 20294 if (opti < args.length && "--full".equals(args[opti])) { 20295 fullPreferred = true; 20296 opti++; 20297 } 20298 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 20299 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 20300 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 20301 dumpState.setDump(DumpState.DUMP_PACKAGES); 20302 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 20303 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 20304 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 20305 dumpState.setDump(DumpState.DUMP_PROVIDERS); 20306 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 20307 dumpState.setDump(DumpState.DUMP_MESSAGES); 20308 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 20309 dumpState.setDump(DumpState.DUMP_VERIFIERS); 20310 } else if ("i".equals(cmd) || "ifv".equals(cmd) 20311 || "intent-filter-verifiers".equals(cmd)) { 20312 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 20313 } else if ("version".equals(cmd)) { 20314 dumpState.setDump(DumpState.DUMP_VERSION); 20315 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 20316 dumpState.setDump(DumpState.DUMP_KEYSETS); 20317 } else if ("installs".equals(cmd)) { 20318 dumpState.setDump(DumpState.DUMP_INSTALLS); 20319 } else if ("frozen".equals(cmd)) { 20320 dumpState.setDump(DumpState.DUMP_FROZEN); 20321 } else if ("dexopt".equals(cmd)) { 20322 dumpState.setDump(DumpState.DUMP_DEXOPT); 20323 } else if ("compiler-stats".equals(cmd)) { 20324 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 20325 } else if ("write".equals(cmd)) { 20326 synchronized (mPackages) { 20327 mSettings.writeLPr(); 20328 pw.println("Settings written."); 20329 return; 20330 } 20331 } 20332 } 20333 20334 if (checkin) { 20335 pw.println("vers,1"); 20336 } 20337 20338 // reader 20339 synchronized (mPackages) { 20340 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 20341 if (!checkin) { 20342 if (dumpState.onTitlePrinted()) 20343 pw.println(); 20344 pw.println("Database versions:"); 20345 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 20346 } 20347 } 20348 20349 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 20350 if (!checkin) { 20351 if (dumpState.onTitlePrinted()) 20352 pw.println(); 20353 pw.println("Verifiers:"); 20354 pw.print(" Required: "); 20355 pw.print(mRequiredVerifierPackage); 20356 pw.print(" (uid="); 20357 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 20358 UserHandle.USER_SYSTEM)); 20359 pw.println(")"); 20360 } else if (mRequiredVerifierPackage != null) { 20361 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 20362 pw.print(","); 20363 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 20364 UserHandle.USER_SYSTEM)); 20365 } 20366 } 20367 20368 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 20369 packageName == null) { 20370 if (mIntentFilterVerifierComponent != null) { 20371 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 20372 if (!checkin) { 20373 if (dumpState.onTitlePrinted()) 20374 pw.println(); 20375 pw.println("Intent Filter Verifier:"); 20376 pw.print(" Using: "); 20377 pw.print(verifierPackageName); 20378 pw.print(" (uid="); 20379 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 20380 UserHandle.USER_SYSTEM)); 20381 pw.println(")"); 20382 } else if (verifierPackageName != null) { 20383 pw.print("ifv,"); pw.print(verifierPackageName); 20384 pw.print(","); 20385 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 20386 UserHandle.USER_SYSTEM)); 20387 } 20388 } else { 20389 pw.println(); 20390 pw.println("No Intent Filter Verifier available!"); 20391 } 20392 } 20393 20394 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 20395 boolean printedHeader = false; 20396 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 20397 while (it.hasNext()) { 20398 String libName = it.next(); 20399 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName); 20400 if (versionedLib == null) { 20401 continue; 20402 } 20403 final int versionCount = versionedLib.size(); 20404 for (int i = 0; i < versionCount; i++) { 20405 SharedLibraryEntry libEntry = versionedLib.valueAt(i); 20406 if (!checkin) { 20407 if (!printedHeader) { 20408 if (dumpState.onTitlePrinted()) 20409 pw.println(); 20410 pw.println("Libraries:"); 20411 printedHeader = true; 20412 } 20413 pw.print(" "); 20414 } else { 20415 pw.print("lib,"); 20416 } 20417 pw.print(libEntry.info.getName()); 20418 if (libEntry.info.isStatic()) { 20419 pw.print(" version=" + libEntry.info.getVersion()); 20420 } 20421 if (!checkin) { 20422 pw.print(" -> "); 20423 } 20424 if (libEntry.path != null) { 20425 pw.print(" (jar) "); 20426 pw.print(libEntry.path); 20427 } else { 20428 pw.print(" (apk) "); 20429 pw.print(libEntry.apk); 20430 } 20431 pw.println(); 20432 } 20433 } 20434 } 20435 20436 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 20437 if (dumpState.onTitlePrinted()) 20438 pw.println(); 20439 if (!checkin) { 20440 pw.println("Features:"); 20441 } 20442 20443 synchronized (mAvailableFeatures) { 20444 for (FeatureInfo feat : mAvailableFeatures.values()) { 20445 if (checkin) { 20446 pw.print("feat,"); 20447 pw.print(feat.name); 20448 pw.print(","); 20449 pw.println(feat.version); 20450 } else { 20451 pw.print(" "); 20452 pw.print(feat.name); 20453 if (feat.version > 0) { 20454 pw.print(" version="); 20455 pw.print(feat.version); 20456 } 20457 pw.println(); 20458 } 20459 } 20460 } 20461 } 20462 20463 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 20464 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 20465 : "Activity Resolver Table:", " ", packageName, 20466 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20467 dumpState.setTitlePrinted(true); 20468 } 20469 } 20470 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 20471 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 20472 : "Receiver Resolver Table:", " ", packageName, 20473 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20474 dumpState.setTitlePrinted(true); 20475 } 20476 } 20477 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 20478 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 20479 : "Service Resolver Table:", " ", packageName, 20480 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20481 dumpState.setTitlePrinted(true); 20482 } 20483 } 20484 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 20485 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 20486 : "Provider Resolver Table:", " ", packageName, 20487 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20488 dumpState.setTitlePrinted(true); 20489 } 20490 } 20491 20492 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 20493 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 20494 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 20495 int user = mSettings.mPreferredActivities.keyAt(i); 20496 if (pir.dump(pw, 20497 dumpState.getTitlePrinted() 20498 ? "\nPreferred Activities User " + user + ":" 20499 : "Preferred Activities User " + user + ":", " ", 20500 packageName, true, false)) { 20501 dumpState.setTitlePrinted(true); 20502 } 20503 } 20504 } 20505 20506 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 20507 pw.flush(); 20508 FileOutputStream fout = new FileOutputStream(fd); 20509 BufferedOutputStream str = new BufferedOutputStream(fout); 20510 XmlSerializer serializer = new FastXmlSerializer(); 20511 try { 20512 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 20513 serializer.startDocument(null, true); 20514 serializer.setFeature( 20515 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 20516 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 20517 serializer.endDocument(); 20518 serializer.flush(); 20519 } catch (IllegalArgumentException e) { 20520 pw.println("Failed writing: " + e); 20521 } catch (IllegalStateException e) { 20522 pw.println("Failed writing: " + e); 20523 } catch (IOException e) { 20524 pw.println("Failed writing: " + e); 20525 } 20526 } 20527 20528 if (!checkin 20529 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 20530 && packageName == null) { 20531 pw.println(); 20532 int count = mSettings.mPackages.size(); 20533 if (count == 0) { 20534 pw.println("No applications!"); 20535 pw.println(); 20536 } else { 20537 final String prefix = " "; 20538 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 20539 if (allPackageSettings.size() == 0) { 20540 pw.println("No domain preferred apps!"); 20541 pw.println(); 20542 } else { 20543 pw.println("App verification status:"); 20544 pw.println(); 20545 count = 0; 20546 for (PackageSetting ps : allPackageSettings) { 20547 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 20548 if (ivi == null || ivi.getPackageName() == null) continue; 20549 pw.println(prefix + "Package: " + ivi.getPackageName()); 20550 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 20551 pw.println(prefix + "Status: " + ivi.getStatusString()); 20552 pw.println(); 20553 count++; 20554 } 20555 if (count == 0) { 20556 pw.println(prefix + "No app verification established."); 20557 pw.println(); 20558 } 20559 for (int userId : sUserManager.getUserIds()) { 20560 pw.println("App linkages for user " + userId + ":"); 20561 pw.println(); 20562 count = 0; 20563 for (PackageSetting ps : allPackageSettings) { 20564 final long status = ps.getDomainVerificationStatusForUser(userId); 20565 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED 20566 && !DEBUG_DOMAIN_VERIFICATION) { 20567 continue; 20568 } 20569 pw.println(prefix + "Package: " + ps.name); 20570 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 20571 String statusStr = IntentFilterVerificationInfo. 20572 getStatusStringFromValue(status); 20573 pw.println(prefix + "Status: " + statusStr); 20574 pw.println(); 20575 count++; 20576 } 20577 if (count == 0) { 20578 pw.println(prefix + "No configured app linkages."); 20579 pw.println(); 20580 } 20581 } 20582 } 20583 } 20584 } 20585 20586 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 20587 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 20588 if (packageName == null && permissionNames == null) { 20589 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 20590 if (iperm == 0) { 20591 if (dumpState.onTitlePrinted()) 20592 pw.println(); 20593 pw.println("AppOp Permissions:"); 20594 } 20595 pw.print(" AppOp Permission "); 20596 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 20597 pw.println(":"); 20598 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 20599 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 20600 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 20601 } 20602 } 20603 } 20604 } 20605 20606 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 20607 boolean printedSomething = false; 20608 for (PackageParser.Provider p : mProviders.mProviders.values()) { 20609 if (packageName != null && !packageName.equals(p.info.packageName)) { 20610 continue; 20611 } 20612 if (!printedSomething) { 20613 if (dumpState.onTitlePrinted()) 20614 pw.println(); 20615 pw.println("Registered ContentProviders:"); 20616 printedSomething = true; 20617 } 20618 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 20619 pw.print(" "); pw.println(p.toString()); 20620 } 20621 printedSomething = false; 20622 for (Map.Entry<String, PackageParser.Provider> entry : 20623 mProvidersByAuthority.entrySet()) { 20624 PackageParser.Provider p = entry.getValue(); 20625 if (packageName != null && !packageName.equals(p.info.packageName)) { 20626 continue; 20627 } 20628 if (!printedSomething) { 20629 if (dumpState.onTitlePrinted()) 20630 pw.println(); 20631 pw.println("ContentProvider Authorities:"); 20632 printedSomething = true; 20633 } 20634 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 20635 pw.print(" "); pw.println(p.toString()); 20636 if (p.info != null && p.info.applicationInfo != null) { 20637 final String appInfo = p.info.applicationInfo.toString(); 20638 pw.print(" applicationInfo="); pw.println(appInfo); 20639 } 20640 } 20641 } 20642 20643 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 20644 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 20645 } 20646 20647 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 20648 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 20649 } 20650 20651 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 20652 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 20653 } 20654 20655 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 20656 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 20657 } 20658 20659 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 20660 // XXX should handle packageName != null by dumping only install data that 20661 // the given package is involved with. 20662 if (dumpState.onTitlePrinted()) pw.println(); 20663 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 20664 } 20665 20666 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 20667 // XXX should handle packageName != null by dumping only install data that 20668 // the given package is involved with. 20669 if (dumpState.onTitlePrinted()) pw.println(); 20670 20671 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20672 ipw.println(); 20673 ipw.println("Frozen packages:"); 20674 ipw.increaseIndent(); 20675 if (mFrozenPackages.size() == 0) { 20676 ipw.println("(none)"); 20677 } else { 20678 for (int i = 0; i < mFrozenPackages.size(); i++) { 20679 ipw.println(mFrozenPackages.valueAt(i)); 20680 } 20681 } 20682 ipw.decreaseIndent(); 20683 } 20684 20685 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 20686 if (dumpState.onTitlePrinted()) pw.println(); 20687 dumpDexoptStateLPr(pw, packageName); 20688 } 20689 20690 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 20691 if (dumpState.onTitlePrinted()) pw.println(); 20692 dumpCompilerStatsLPr(pw, packageName); 20693 } 20694 20695 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 20696 if (dumpState.onTitlePrinted()) pw.println(); 20697 mSettings.dumpReadMessagesLPr(pw, dumpState); 20698 20699 pw.println(); 20700 pw.println("Package warning messages:"); 20701 BufferedReader in = null; 20702 String line = null; 20703 try { 20704 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20705 while ((line = in.readLine()) != null) { 20706 if (line.contains("ignored: updated version")) continue; 20707 pw.println(line); 20708 } 20709 } catch (IOException ignored) { 20710 } finally { 20711 IoUtils.closeQuietly(in); 20712 } 20713 } 20714 20715 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 20716 BufferedReader in = null; 20717 String line = null; 20718 try { 20719 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20720 while ((line = in.readLine()) != null) { 20721 if (line.contains("ignored: updated version")) continue; 20722 pw.print("msg,"); 20723 pw.println(line); 20724 } 20725 } catch (IOException ignored) { 20726 } finally { 20727 IoUtils.closeQuietly(in); 20728 } 20729 } 20730 } 20731 } 20732 20733 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 20734 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20735 ipw.println(); 20736 ipw.println("Dexopt state:"); 20737 ipw.increaseIndent(); 20738 Collection<PackageParser.Package> packages = null; 20739 if (packageName != null) { 20740 PackageParser.Package targetPackage = mPackages.get(packageName); 20741 if (targetPackage != null) { 20742 packages = Collections.singletonList(targetPackage); 20743 } else { 20744 ipw.println("Unable to find package: " + packageName); 20745 return; 20746 } 20747 } else { 20748 packages = mPackages.values(); 20749 } 20750 20751 for (PackageParser.Package pkg : packages) { 20752 ipw.println("[" + pkg.packageName + "]"); 20753 ipw.increaseIndent(); 20754 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 20755 ipw.decreaseIndent(); 20756 } 20757 } 20758 20759 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 20760 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20761 ipw.println(); 20762 ipw.println("Compiler stats:"); 20763 ipw.increaseIndent(); 20764 Collection<PackageParser.Package> packages = null; 20765 if (packageName != null) { 20766 PackageParser.Package targetPackage = mPackages.get(packageName); 20767 if (targetPackage != null) { 20768 packages = Collections.singletonList(targetPackage); 20769 } else { 20770 ipw.println("Unable to find package: " + packageName); 20771 return; 20772 } 20773 } else { 20774 packages = mPackages.values(); 20775 } 20776 20777 for (PackageParser.Package pkg : packages) { 20778 ipw.println("[" + pkg.packageName + "]"); 20779 ipw.increaseIndent(); 20780 20781 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 20782 if (stats == null) { 20783 ipw.println("(No recorded stats)"); 20784 } else { 20785 stats.dump(ipw); 20786 } 20787 ipw.decreaseIndent(); 20788 } 20789 } 20790 20791 private String dumpDomainString(String packageName) { 20792 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 20793 .getList(); 20794 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 20795 20796 ArraySet<String> result = new ArraySet<>(); 20797 if (iviList.size() > 0) { 20798 for (IntentFilterVerificationInfo ivi : iviList) { 20799 for (String host : ivi.getDomains()) { 20800 result.add(host); 20801 } 20802 } 20803 } 20804 if (filters != null && filters.size() > 0) { 20805 for (IntentFilter filter : filters) { 20806 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 20807 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 20808 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 20809 result.addAll(filter.getHostsList()); 20810 } 20811 } 20812 } 20813 20814 StringBuilder sb = new StringBuilder(result.size() * 16); 20815 for (String domain : result) { 20816 if (sb.length() > 0) sb.append(" "); 20817 sb.append(domain); 20818 } 20819 return sb.toString(); 20820 } 20821 20822 // ------- apps on sdcard specific code ------- 20823 static final boolean DEBUG_SD_INSTALL = false; 20824 20825 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 20826 20827 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 20828 20829 private boolean mMediaMounted = false; 20830 20831 static String getEncryptKey() { 20832 try { 20833 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 20834 SD_ENCRYPTION_KEYSTORE_NAME); 20835 if (sdEncKey == null) { 20836 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 20837 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 20838 if (sdEncKey == null) { 20839 Slog.e(TAG, "Failed to create encryption keys"); 20840 return null; 20841 } 20842 } 20843 return sdEncKey; 20844 } catch (NoSuchAlgorithmException nsae) { 20845 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 20846 return null; 20847 } catch (IOException ioe) { 20848 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 20849 return null; 20850 } 20851 } 20852 20853 /* 20854 * Update media status on PackageManager. 20855 */ 20856 @Override 20857 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 20858 int callingUid = Binder.getCallingUid(); 20859 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 20860 throw new SecurityException("Media status can only be updated by the system"); 20861 } 20862 // reader; this apparently protects mMediaMounted, but should probably 20863 // be a different lock in that case. 20864 synchronized (mPackages) { 20865 Log.i(TAG, "Updating external media status from " 20866 + (mMediaMounted ? "mounted" : "unmounted") + " to " 20867 + (mediaStatus ? "mounted" : "unmounted")); 20868 if (DEBUG_SD_INSTALL) 20869 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 20870 + ", mMediaMounted=" + mMediaMounted); 20871 if (mediaStatus == mMediaMounted) { 20872 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 20873 : 0, -1); 20874 mHandler.sendMessage(msg); 20875 return; 20876 } 20877 mMediaMounted = mediaStatus; 20878 } 20879 // Queue up an async operation since the package installation may take a 20880 // little while. 20881 mHandler.post(new Runnable() { 20882 public void run() { 20883 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 20884 } 20885 }); 20886 } 20887 20888 /** 20889 * Called by StorageManagerService when the initial ASECs to scan are available. 20890 * Should block until all the ASEC containers are finished being scanned. 20891 */ 20892 public void scanAvailableAsecs() { 20893 updateExternalMediaStatusInner(true, false, false); 20894 } 20895 20896 /* 20897 * Collect information of applications on external media, map them against 20898 * existing containers and update information based on current mount status. 20899 * Please note that we always have to report status if reportStatus has been 20900 * set to true especially when unloading packages. 20901 */ 20902 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 20903 boolean externalStorage) { 20904 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 20905 int[] uidArr = EmptyArray.INT; 20906 20907 final String[] list = PackageHelper.getSecureContainerList(); 20908 if (ArrayUtils.isEmpty(list)) { 20909 Log.i(TAG, "No secure containers found"); 20910 } else { 20911 // Process list of secure containers and categorize them 20912 // as active or stale based on their package internal state. 20913 20914 // reader 20915 synchronized (mPackages) { 20916 for (String cid : list) { 20917 // Leave stages untouched for now; installer service owns them 20918 if (PackageInstallerService.isStageName(cid)) continue; 20919 20920 if (DEBUG_SD_INSTALL) 20921 Log.i(TAG, "Processing container " + cid); 20922 String pkgName = getAsecPackageName(cid); 20923 if (pkgName == null) { 20924 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 20925 continue; 20926 } 20927 if (DEBUG_SD_INSTALL) 20928 Log.i(TAG, "Looking for pkg : " + pkgName); 20929 20930 final PackageSetting ps = mSettings.mPackages.get(pkgName); 20931 if (ps == null) { 20932 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 20933 continue; 20934 } 20935 20936 /* 20937 * Skip packages that are not external if we're unmounting 20938 * external storage. 20939 */ 20940 if (externalStorage && !isMounted && !isExternal(ps)) { 20941 continue; 20942 } 20943 20944 final AsecInstallArgs args = new AsecInstallArgs(cid, 20945 getAppDexInstructionSets(ps), ps.isForwardLocked()); 20946 // The package status is changed only if the code path 20947 // matches between settings and the container id. 20948 if (ps.codePathString != null 20949 && ps.codePathString.startsWith(args.getCodePath())) { 20950 if (DEBUG_SD_INSTALL) { 20951 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 20952 + " at code path: " + ps.codePathString); 20953 } 20954 20955 // We do have a valid package installed on sdcard 20956 processCids.put(args, ps.codePathString); 20957 final int uid = ps.appId; 20958 if (uid != -1) { 20959 uidArr = ArrayUtils.appendInt(uidArr, uid); 20960 } 20961 } else { 20962 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 20963 + ps.codePathString); 20964 } 20965 } 20966 } 20967 20968 Arrays.sort(uidArr); 20969 } 20970 20971 // Process packages with valid entries. 20972 if (isMounted) { 20973 if (DEBUG_SD_INSTALL) 20974 Log.i(TAG, "Loading packages"); 20975 loadMediaPackages(processCids, uidArr, externalStorage); 20976 startCleaningPackages(); 20977 mInstallerService.onSecureContainersAvailable(); 20978 } else { 20979 if (DEBUG_SD_INSTALL) 20980 Log.i(TAG, "Unloading packages"); 20981 unloadMediaPackages(processCids, uidArr, reportStatus); 20982 } 20983 } 20984 20985 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 20986 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 20987 final int size = infos.size(); 20988 final String[] packageNames = new String[size]; 20989 final int[] packageUids = new int[size]; 20990 for (int i = 0; i < size; i++) { 20991 final ApplicationInfo info = infos.get(i); 20992 packageNames[i] = info.packageName; 20993 packageUids[i] = info.uid; 20994 } 20995 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 20996 finishedReceiver); 20997 } 20998 20999 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21000 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 21001 sendResourcesChangedBroadcast(mediaStatus, replacing, 21002 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 21003 } 21004 21005 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21006 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 21007 int size = pkgList.length; 21008 if (size > 0) { 21009 // Send broadcasts here 21010 Bundle extras = new Bundle(); 21011 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 21012 if (uidArr != null) { 21013 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 21014 } 21015 if (replacing) { 21016 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 21017 } 21018 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 21019 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 21020 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 21021 } 21022 } 21023 21024 /* 21025 * Look at potentially valid container ids from processCids If package 21026 * information doesn't match the one on record or package scanning fails, 21027 * the cid is added to list of removeCids. We currently don't delete stale 21028 * containers. 21029 */ 21030 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 21031 boolean externalStorage) { 21032 ArrayList<String> pkgList = new ArrayList<String>(); 21033 Set<AsecInstallArgs> keys = processCids.keySet(); 21034 21035 for (AsecInstallArgs args : keys) { 21036 String codePath = processCids.get(args); 21037 if (DEBUG_SD_INSTALL) 21038 Log.i(TAG, "Loading container : " + args.cid); 21039 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 21040 try { 21041 // Make sure there are no container errors first. 21042 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 21043 Slog.e(TAG, "Failed to mount cid : " + args.cid 21044 + " when installing from sdcard"); 21045 continue; 21046 } 21047 // Check code path here. 21048 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 21049 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 21050 + " does not match one in settings " + codePath); 21051 continue; 21052 } 21053 // Parse package 21054 int parseFlags = mDefParseFlags; 21055 if (args.isExternalAsec()) { 21056 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 21057 } 21058 if (args.isFwdLocked()) { 21059 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 21060 } 21061 21062 synchronized (mInstallLock) { 21063 PackageParser.Package pkg = null; 21064 try { 21065 // Sadly we don't know the package name yet to freeze it 21066 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 21067 SCAN_IGNORE_FROZEN, 0, null); 21068 } catch (PackageManagerException e) { 21069 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 21070 } 21071 // Scan the package 21072 if (pkg != null) { 21073 /* 21074 * TODO why is the lock being held? doPostInstall is 21075 * called in other places without the lock. This needs 21076 * to be straightened out. 21077 */ 21078 // writer 21079 synchronized (mPackages) { 21080 retCode = PackageManager.INSTALL_SUCCEEDED; 21081 pkgList.add(pkg.packageName); 21082 // Post process args 21083 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 21084 pkg.applicationInfo.uid); 21085 } 21086 } else { 21087 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 21088 } 21089 } 21090 21091 } finally { 21092 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 21093 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 21094 } 21095 } 21096 } 21097 // writer 21098 synchronized (mPackages) { 21099 // If the platform SDK has changed since the last time we booted, 21100 // we need to re-grant app permission to catch any new ones that 21101 // appear. This is really a hack, and means that apps can in some 21102 // cases get permissions that the user didn't initially explicitly 21103 // allow... it would be nice to have some better way to handle 21104 // this situation. 21105 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 21106 : mSettings.getInternalVersion(); 21107 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 21108 : StorageManager.UUID_PRIVATE_INTERNAL; 21109 21110 int updateFlags = UPDATE_PERMISSIONS_ALL; 21111 if (ver.sdkVersion != mSdkVersion) { 21112 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 21113 + mSdkVersion + "; regranting permissions for external"); 21114 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 21115 } 21116 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 21117 21118 // Yay, everything is now upgraded 21119 ver.forceCurrent(); 21120 21121 // can downgrade to reader 21122 // Persist settings 21123 mSettings.writeLPr(); 21124 } 21125 // Send a broadcast to let everyone know we are done processing 21126 if (pkgList.size() > 0) { 21127 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 21128 } 21129 } 21130 21131 /* 21132 * Utility method to unload a list of specified containers 21133 */ 21134 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 21135 // Just unmount all valid containers. 21136 for (AsecInstallArgs arg : cidArgs) { 21137 synchronized (mInstallLock) { 21138 arg.doPostDeleteLI(false); 21139 } 21140 } 21141 } 21142 21143 /* 21144 * Unload packages mounted on external media. This involves deleting package 21145 * data from internal structures, sending broadcasts about disabled packages, 21146 * gc'ing to free up references, unmounting all secure containers 21147 * corresponding to packages on external media, and posting a 21148 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 21149 * that we always have to post this message if status has been requested no 21150 * matter what. 21151 */ 21152 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 21153 final boolean reportStatus) { 21154 if (DEBUG_SD_INSTALL) 21155 Log.i(TAG, "unloading media packages"); 21156 ArrayList<String> pkgList = new ArrayList<String>(); 21157 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 21158 final Set<AsecInstallArgs> keys = processCids.keySet(); 21159 for (AsecInstallArgs args : keys) { 21160 String pkgName = args.getPackageName(); 21161 if (DEBUG_SD_INSTALL) 21162 Log.i(TAG, "Trying to unload pkg : " + pkgName); 21163 // Delete package internally 21164 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 21165 synchronized (mInstallLock) { 21166 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 21167 final boolean res; 21168 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 21169 "unloadMediaPackages")) { 21170 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 21171 null); 21172 } 21173 if (res) { 21174 pkgList.add(pkgName); 21175 } else { 21176 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 21177 failedList.add(args); 21178 } 21179 } 21180 } 21181 21182 // reader 21183 synchronized (mPackages) { 21184 // We didn't update the settings after removing each package; 21185 // write them now for all packages. 21186 mSettings.writeLPr(); 21187 } 21188 21189 // We have to absolutely send UPDATED_MEDIA_STATUS only 21190 // after confirming that all the receivers processed the ordered 21191 // broadcast when packages get disabled, force a gc to clean things up. 21192 // and unload all the containers. 21193 if (pkgList.size() > 0) { 21194 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 21195 new IIntentReceiver.Stub() { 21196 public void performReceive(Intent intent, int resultCode, String data, 21197 Bundle extras, boolean ordered, boolean sticky, 21198 int sendingUser) throws RemoteException { 21199 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 21200 reportStatus ? 1 : 0, 1, keys); 21201 mHandler.sendMessage(msg); 21202 } 21203 }); 21204 } else { 21205 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 21206 keys); 21207 mHandler.sendMessage(msg); 21208 } 21209 } 21210 21211 private void loadPrivatePackages(final VolumeInfo vol) { 21212 mHandler.post(new Runnable() { 21213 @Override 21214 public void run() { 21215 loadPrivatePackagesInner(vol); 21216 } 21217 }); 21218 } 21219 21220 private void loadPrivatePackagesInner(VolumeInfo vol) { 21221 final String volumeUuid = vol.fsUuid; 21222 if (TextUtils.isEmpty(volumeUuid)) { 21223 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 21224 return; 21225 } 21226 21227 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 21228 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 21229 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 21230 21231 final VersionInfo ver; 21232 final List<PackageSetting> packages; 21233 synchronized (mPackages) { 21234 ver = mSettings.findOrCreateVersion(volumeUuid); 21235 packages = mSettings.getVolumePackagesLPr(volumeUuid); 21236 } 21237 21238 for (PackageSetting ps : packages) { 21239 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 21240 synchronized (mInstallLock) { 21241 final PackageParser.Package pkg; 21242 try { 21243 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 21244 loaded.add(pkg.applicationInfo); 21245 21246 } catch (PackageManagerException e) { 21247 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 21248 } 21249 21250 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 21251 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 21252 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 21253 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 21254 } 21255 } 21256 } 21257 21258 // Reconcile app data for all started/unlocked users 21259 final StorageManager sm = mContext.getSystemService(StorageManager.class); 21260 final UserManager um = mContext.getSystemService(UserManager.class); 21261 UserManagerInternal umInternal = getUserManagerInternal(); 21262 for (UserInfo user : um.getUsers()) { 21263 final int flags; 21264 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 21265 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 21266 } else if (umInternal.isUserRunning(user.id)) { 21267 flags = StorageManager.FLAG_STORAGE_DE; 21268 } else { 21269 continue; 21270 } 21271 21272 try { 21273 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 21274 synchronized (mInstallLock) { 21275 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */); 21276 } 21277 } catch (IllegalStateException e) { 21278 // Device was probably ejected, and we'll process that event momentarily 21279 Slog.w(TAG, "Failed to prepare storage: " + e); 21280 } 21281 } 21282 21283 synchronized (mPackages) { 21284 int updateFlags = UPDATE_PERMISSIONS_ALL; 21285 if (ver.sdkVersion != mSdkVersion) { 21286 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 21287 + mSdkVersion + "; regranting permissions for " + volumeUuid); 21288 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 21289 } 21290 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 21291 21292 // Yay, everything is now upgraded 21293 ver.forceCurrent(); 21294 21295 mSettings.writeLPr(); 21296 } 21297 21298 for (PackageFreezer freezer : freezers) { 21299 freezer.close(); 21300 } 21301 21302 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 21303 sendResourcesChangedBroadcast(true, false, loaded, null); 21304 } 21305 21306 private void unloadPrivatePackages(final VolumeInfo vol) { 21307 mHandler.post(new Runnable() { 21308 @Override 21309 public void run() { 21310 unloadPrivatePackagesInner(vol); 21311 } 21312 }); 21313 } 21314 21315 private void unloadPrivatePackagesInner(VolumeInfo vol) { 21316 final String volumeUuid = vol.fsUuid; 21317 if (TextUtils.isEmpty(volumeUuid)) { 21318 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 21319 return; 21320 } 21321 21322 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 21323 synchronized (mInstallLock) { 21324 synchronized (mPackages) { 21325 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 21326 for (PackageSetting ps : packages) { 21327 if (ps.pkg == null) continue; 21328 21329 final ApplicationInfo info = ps.pkg.applicationInfo; 21330 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 21331 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 21332 21333 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 21334 "unloadPrivatePackagesInner")) { 21335 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 21336 false, null)) { 21337 unloaded.add(info); 21338 } else { 21339 Slog.w(TAG, "Failed to unload " + ps.codePath); 21340 } 21341 } 21342 21343 // Try very hard to release any references to this package 21344 // so we don't risk the system server being killed due to 21345 // open FDs 21346 AttributeCache.instance().removePackage(ps.name); 21347 } 21348 21349 mSettings.writeLPr(); 21350 } 21351 } 21352 21353 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 21354 sendResourcesChangedBroadcast(false, false, unloaded, null); 21355 21356 // Try very hard to release any references to this path so we don't risk 21357 // the system server being killed due to open FDs 21358 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 21359 21360 for (int i = 0; i < 3; i++) { 21361 System.gc(); 21362 System.runFinalization(); 21363 } 21364 } 21365 21366 private void assertPackageKnown(String volumeUuid, String packageName) 21367 throws PackageManagerException { 21368 synchronized (mPackages) { 21369 // Normalize package name to handle renamed packages 21370 packageName = normalizePackageNameLPr(packageName); 21371 21372 final PackageSetting ps = mSettings.mPackages.get(packageName); 21373 if (ps == null) { 21374 throw new PackageManagerException("Package " + packageName + " is unknown"); 21375 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 21376 throw new PackageManagerException( 21377 "Package " + packageName + " found on unknown volume " + volumeUuid 21378 + "; expected volume " + ps.volumeUuid); 21379 } 21380 } 21381 } 21382 21383 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 21384 throws PackageManagerException { 21385 synchronized (mPackages) { 21386 // Normalize package name to handle renamed packages 21387 packageName = normalizePackageNameLPr(packageName); 21388 21389 final PackageSetting ps = mSettings.mPackages.get(packageName); 21390 if (ps == null) { 21391 throw new PackageManagerException("Package " + packageName + " is unknown"); 21392 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 21393 throw new PackageManagerException( 21394 "Package " + packageName + " found on unknown volume " + volumeUuid 21395 + "; expected volume " + ps.volumeUuid); 21396 } else if (!ps.getInstalled(userId)) { 21397 throw new PackageManagerException( 21398 "Package " + packageName + " not installed for user " + userId); 21399 } 21400 } 21401 } 21402 21403 private List<String> collectAbsoluteCodePaths() { 21404 synchronized (mPackages) { 21405 List<String> codePaths = new ArrayList<>(); 21406 final int packageCount = mSettings.mPackages.size(); 21407 for (int i = 0; i < packageCount; i++) { 21408 final PackageSetting ps = mSettings.mPackages.valueAt(i); 21409 codePaths.add(ps.codePath.getAbsolutePath()); 21410 } 21411 return codePaths; 21412 } 21413 } 21414 21415 /** 21416 * Examine all apps present on given mounted volume, and destroy apps that 21417 * aren't expected, either due to uninstallation or reinstallation on 21418 * another volume. 21419 */ 21420 private void reconcileApps(String volumeUuid) { 21421 List<String> absoluteCodePaths = collectAbsoluteCodePaths(); 21422 List<File> filesToDelete = null; 21423 21424 final File[] files = FileUtils.listFilesOrEmpty( 21425 Environment.getDataAppDirectory(volumeUuid)); 21426 for (File file : files) { 21427 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 21428 && !PackageInstallerService.isStageName(file.getName()); 21429 if (!isPackage) { 21430 // Ignore entries which are not packages 21431 continue; 21432 } 21433 21434 String absolutePath = file.getAbsolutePath(); 21435 21436 boolean pathValid = false; 21437 final int absoluteCodePathCount = absoluteCodePaths.size(); 21438 for (int i = 0; i < absoluteCodePathCount; i++) { 21439 String absoluteCodePath = absoluteCodePaths.get(i); 21440 if (absolutePath.startsWith(absoluteCodePath)) { 21441 pathValid = true; 21442 break; 21443 } 21444 } 21445 21446 if (!pathValid) { 21447 if (filesToDelete == null) { 21448 filesToDelete = new ArrayList<>(); 21449 } 21450 filesToDelete.add(file); 21451 } 21452 } 21453 21454 if (filesToDelete != null) { 21455 final int fileToDeleteCount = filesToDelete.size(); 21456 for (int i = 0; i < fileToDeleteCount; i++) { 21457 File fileToDelete = filesToDelete.get(i); 21458 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete); 21459 synchronized (mInstallLock) { 21460 removeCodePathLI(fileToDelete); 21461 } 21462 } 21463 } 21464 } 21465 21466 /** 21467 * Reconcile all app data for the given user. 21468 * <p> 21469 * Verifies that directories exist and that ownership and labeling is 21470 * correct for all installed apps on all mounted volumes. 21471 */ 21472 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) { 21473 final StorageManager storage = mContext.getSystemService(StorageManager.class); 21474 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 21475 final String volumeUuid = vol.getFsUuid(); 21476 synchronized (mInstallLock) { 21477 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData); 21478 } 21479 } 21480 } 21481 21482 /** 21483 * Reconcile all app data on given mounted volume. 21484 * <p> 21485 * Destroys app data that isn't expected, either due to uninstallation or 21486 * reinstallation on another volume. 21487 * <p> 21488 * Verifies that directories exist and that ownership and labeling is 21489 * correct for all installed apps. 21490 */ 21491 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags, 21492 boolean migrateAppData) { 21493 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 21494 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData); 21495 21496 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 21497 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 21498 21499 // First look for stale data that doesn't belong, and check if things 21500 // have changed since we did our last restorecon 21501 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 21502 if (StorageManager.isFileEncryptedNativeOrEmulated() 21503 && !StorageManager.isUserKeyUnlocked(userId)) { 21504 throw new RuntimeException( 21505 "Yikes, someone asked us to reconcile CE storage while " + userId 21506 + " was still locked; this would have caused massive data loss!"); 21507 } 21508 21509 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 21510 for (File file : files) { 21511 final String packageName = file.getName(); 21512 try { 21513 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 21514 } catch (PackageManagerException e) { 21515 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 21516 try { 21517 mInstaller.destroyAppData(volumeUuid, packageName, userId, 21518 StorageManager.FLAG_STORAGE_CE, 0); 21519 } catch (InstallerException e2) { 21520 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 21521 } 21522 } 21523 } 21524 } 21525 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 21526 final File[] files = FileUtils.listFilesOrEmpty(deDir); 21527 for (File file : files) { 21528 final String packageName = file.getName(); 21529 try { 21530 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 21531 } catch (PackageManagerException e) { 21532 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 21533 try { 21534 mInstaller.destroyAppData(volumeUuid, packageName, userId, 21535 StorageManager.FLAG_STORAGE_DE, 0); 21536 } catch (InstallerException e2) { 21537 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 21538 } 21539 } 21540 } 21541 } 21542 21543 // Ensure that data directories are ready to roll for all packages 21544 // installed for this volume and user 21545 final List<PackageSetting> packages; 21546 synchronized (mPackages) { 21547 packages = mSettings.getVolumePackagesLPr(volumeUuid); 21548 } 21549 int preparedCount = 0; 21550 for (PackageSetting ps : packages) { 21551 final String packageName = ps.name; 21552 if (ps.pkg == null) { 21553 Slog.w(TAG, "Odd, missing scanned package " + packageName); 21554 // TODO: might be due to legacy ASEC apps; we should circle back 21555 // and reconcile again once they're scanned 21556 continue; 21557 } 21558 21559 if (ps.getInstalled(userId)) { 21560 prepareAppDataLIF(ps.pkg, userId, flags); 21561 21562 if (migrateAppData && maybeMigrateAppDataLIF(ps.pkg, userId)) { 21563 // We may have just shuffled around app data directories, so 21564 // prepare them one more time 21565 prepareAppDataLIF(ps.pkg, userId, flags); 21566 } 21567 21568 preparedCount++; 21569 } 21570 } 21571 21572 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); 21573 } 21574 21575 /** 21576 * Prepare app data for the given app just after it was installed or 21577 * upgraded. This method carefully only touches users that it's installed 21578 * for, and it forces a restorecon to handle any seinfo changes. 21579 * <p> 21580 * Verifies that directories exist and that ownership and labeling is 21581 * correct for all installed apps. If there is an ownership mismatch, it 21582 * will try recovering system apps by wiping data; third-party app data is 21583 * left intact. 21584 * <p> 21585 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 21586 */ 21587 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 21588 final PackageSetting ps; 21589 synchronized (mPackages) { 21590 ps = mSettings.mPackages.get(pkg.packageName); 21591 mSettings.writeKernelMappingLPr(ps); 21592 } 21593 21594 final UserManager um = mContext.getSystemService(UserManager.class); 21595 UserManagerInternal umInternal = getUserManagerInternal(); 21596 for (UserInfo user : um.getUsers()) { 21597 final int flags; 21598 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 21599 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 21600 } else if (umInternal.isUserRunning(user.id)) { 21601 flags = StorageManager.FLAG_STORAGE_DE; 21602 } else { 21603 continue; 21604 } 21605 21606 if (ps.getInstalled(user.id)) { 21607 // TODO: when user data is locked, mark that we're still dirty 21608 prepareAppDataLIF(pkg, user.id, flags); 21609 } 21610 } 21611 } 21612 21613 /** 21614 * Prepare app data for the given app. 21615 * <p> 21616 * Verifies that directories exist and that ownership and labeling is 21617 * correct for all installed apps. If there is an ownership mismatch, this 21618 * will try recovering system apps by wiping data; third-party app data is 21619 * left intact. 21620 */ 21621 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 21622 if (pkg == null) { 21623 Slog.wtf(TAG, "Package was null!", new Throwable()); 21624 return; 21625 } 21626 prepareAppDataLeafLIF(pkg, userId, flags); 21627 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 21628 for (int i = 0; i < childCount; i++) { 21629 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 21630 } 21631 } 21632 21633 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 21634 if (DEBUG_APP_DATA) { 21635 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 21636 + Integer.toHexString(flags)); 21637 } 21638 21639 final String volumeUuid = pkg.volumeUuid; 21640 final String packageName = pkg.packageName; 21641 final ApplicationInfo app = pkg.applicationInfo; 21642 final int appId = UserHandle.getAppId(app.uid); 21643 21644 Preconditions.checkNotNull(app.seInfo); 21645 21646 long ceDataInode = -1; 21647 try { 21648 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 21649 appId, app.seInfo, app.targetSdkVersion); 21650 } catch (InstallerException e) { 21651 if (app.isSystemApp()) { 21652 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 21653 + ", but trying to recover: " + e); 21654 destroyAppDataLeafLIF(pkg, userId, flags); 21655 try { 21656 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 21657 appId, app.seInfo, app.targetSdkVersion); 21658 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 21659 } catch (InstallerException e2) { 21660 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 21661 } 21662 } else { 21663 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 21664 } 21665 } 21666 21667 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { 21668 // TODO: mark this structure as dirty so we persist it! 21669 synchronized (mPackages) { 21670 final PackageSetting ps = mSettings.mPackages.get(packageName); 21671 if (ps != null) { 21672 ps.setCeDataInode(ceDataInode, userId); 21673 } 21674 } 21675 } 21676 21677 prepareAppDataContentsLeafLIF(pkg, userId, flags); 21678 } 21679 21680 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 21681 if (pkg == null) { 21682 Slog.wtf(TAG, "Package was null!", new Throwable()); 21683 return; 21684 } 21685 prepareAppDataContentsLeafLIF(pkg, userId, flags); 21686 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 21687 for (int i = 0; i < childCount; i++) { 21688 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 21689 } 21690 } 21691 21692 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 21693 final String volumeUuid = pkg.volumeUuid; 21694 final String packageName = pkg.packageName; 21695 final ApplicationInfo app = pkg.applicationInfo; 21696 21697 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 21698 // Create a native library symlink only if we have native libraries 21699 // and if the native libraries are 32 bit libraries. We do not provide 21700 // this symlink for 64 bit libraries. 21701 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 21702 final String nativeLibPath = app.nativeLibraryDir; 21703 try { 21704 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 21705 nativeLibPath, userId); 21706 } catch (InstallerException e) { 21707 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 21708 } 21709 } 21710 } 21711 } 21712 21713 /** 21714 * For system apps on non-FBE devices, this method migrates any existing 21715 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 21716 * requested by the app. 21717 */ 21718 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 21719 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 21720 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 21721 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 21722 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 21723 try { 21724 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 21725 storageTarget); 21726 } catch (InstallerException e) { 21727 logCriticalInfo(Log.WARN, 21728 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 21729 } 21730 return true; 21731 } else { 21732 return false; 21733 } 21734 } 21735 21736 public PackageFreezer freezePackage(String packageName, String killReason) { 21737 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 21738 } 21739 21740 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 21741 return new PackageFreezer(packageName, userId, killReason); 21742 } 21743 21744 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 21745 String killReason) { 21746 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 21747 } 21748 21749 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 21750 String killReason) { 21751 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 21752 return new PackageFreezer(); 21753 } else { 21754 return freezePackage(packageName, userId, killReason); 21755 } 21756 } 21757 21758 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 21759 String killReason) { 21760 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 21761 } 21762 21763 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 21764 String killReason) { 21765 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 21766 return new PackageFreezer(); 21767 } else { 21768 return freezePackage(packageName, userId, killReason); 21769 } 21770 } 21771 21772 /** 21773 * Class that freezes and kills the given package upon creation, and 21774 * unfreezes it upon closing. This is typically used when doing surgery on 21775 * app code/data to prevent the app from running while you're working. 21776 */ 21777 private class PackageFreezer implements AutoCloseable { 21778 private final String mPackageName; 21779 private final PackageFreezer[] mChildren; 21780 21781 private final boolean mWeFroze; 21782 21783 private final AtomicBoolean mClosed = new AtomicBoolean(); 21784 private final CloseGuard mCloseGuard = CloseGuard.get(); 21785 21786 /** 21787 * Create and return a stub freezer that doesn't actually do anything, 21788 * typically used when someone requested 21789 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 21790 * {@link PackageManager#DELETE_DONT_KILL_APP}. 21791 */ 21792 public PackageFreezer() { 21793 mPackageName = null; 21794 mChildren = null; 21795 mWeFroze = false; 21796 mCloseGuard.open("close"); 21797 } 21798 21799 public PackageFreezer(String packageName, int userId, String killReason) { 21800 synchronized (mPackages) { 21801 mPackageName = packageName; 21802 mWeFroze = mFrozenPackages.add(mPackageName); 21803 21804 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 21805 if (ps != null) { 21806 killApplication(ps.name, ps.appId, userId, killReason); 21807 } 21808 21809 final PackageParser.Package p = mPackages.get(packageName); 21810 if (p != null && p.childPackages != null) { 21811 final int N = p.childPackages.size(); 21812 mChildren = new PackageFreezer[N]; 21813 for (int i = 0; i < N; i++) { 21814 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 21815 userId, killReason); 21816 } 21817 } else { 21818 mChildren = null; 21819 } 21820 } 21821 mCloseGuard.open("close"); 21822 } 21823 21824 @Override 21825 protected void finalize() throws Throwable { 21826 try { 21827 mCloseGuard.warnIfOpen(); 21828 close(); 21829 } finally { 21830 super.finalize(); 21831 } 21832 } 21833 21834 @Override 21835 public void close() { 21836 mCloseGuard.close(); 21837 if (mClosed.compareAndSet(false, true)) { 21838 synchronized (mPackages) { 21839 if (mWeFroze) { 21840 mFrozenPackages.remove(mPackageName); 21841 } 21842 21843 if (mChildren != null) { 21844 for (PackageFreezer freezer : mChildren) { 21845 freezer.close(); 21846 } 21847 } 21848 } 21849 } 21850 } 21851 } 21852 21853 /** 21854 * Verify that given package is currently frozen. 21855 */ 21856 private void checkPackageFrozen(String packageName) { 21857 synchronized (mPackages) { 21858 if (!mFrozenPackages.contains(packageName)) { 21859 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 21860 } 21861 } 21862 } 21863 21864 @Override 21865 public int movePackage(final String packageName, final String volumeUuid) { 21866 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 21867 21868 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 21869 final int moveId = mNextMoveId.getAndIncrement(); 21870 mHandler.post(new Runnable() { 21871 @Override 21872 public void run() { 21873 try { 21874 movePackageInternal(packageName, volumeUuid, moveId, user); 21875 } catch (PackageManagerException e) { 21876 Slog.w(TAG, "Failed to move " + packageName, e); 21877 mMoveCallbacks.notifyStatusChanged(moveId, 21878 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 21879 } 21880 } 21881 }); 21882 return moveId; 21883 } 21884 21885 private void movePackageInternal(final String packageName, final String volumeUuid, 21886 final int moveId, UserHandle user) throws PackageManagerException { 21887 final StorageManager storage = mContext.getSystemService(StorageManager.class); 21888 final PackageManager pm = mContext.getPackageManager(); 21889 21890 final boolean currentAsec; 21891 final String currentVolumeUuid; 21892 final File codeFile; 21893 final String installerPackageName; 21894 final String packageAbiOverride; 21895 final int appId; 21896 final String seinfo; 21897 final String label; 21898 final int targetSdkVersion; 21899 final PackageFreezer freezer; 21900 final int[] installedUserIds; 21901 21902 // reader 21903 synchronized (mPackages) { 21904 final PackageParser.Package pkg = mPackages.get(packageName); 21905 final PackageSetting ps = mSettings.mPackages.get(packageName); 21906 if (pkg == null || ps == null) { 21907 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 21908 } 21909 21910 if (pkg.applicationInfo.isSystemApp()) { 21911 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 21912 "Cannot move system application"); 21913 } 21914 21915 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid); 21916 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean( 21917 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal); 21918 if (isInternalStorage && !allow3rdPartyOnInternal) { 21919 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL, 21920 "3rd party apps are not allowed on internal storage"); 21921 } 21922 21923 if (pkg.applicationInfo.isExternalAsec()) { 21924 currentAsec = true; 21925 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 21926 } else if (pkg.applicationInfo.isForwardLocked()) { 21927 currentAsec = true; 21928 currentVolumeUuid = "forward_locked"; 21929 } else { 21930 currentAsec = false; 21931 currentVolumeUuid = ps.volumeUuid; 21932 21933 final File probe = new File(pkg.codePath); 21934 final File probeOat = new File(probe, "oat"); 21935 if (!probe.isDirectory() || !probeOat.isDirectory()) { 21936 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 21937 "Move only supported for modern cluster style installs"); 21938 } 21939 } 21940 21941 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 21942 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 21943 "Package already moved to " + volumeUuid); 21944 } 21945 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 21946 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 21947 "Device admin cannot be moved"); 21948 } 21949 21950 if (mFrozenPackages.contains(packageName)) { 21951 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 21952 "Failed to move already frozen package"); 21953 } 21954 21955 codeFile = new File(pkg.codePath); 21956 installerPackageName = ps.installerPackageName; 21957 packageAbiOverride = ps.cpuAbiOverrideString; 21958 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 21959 seinfo = pkg.applicationInfo.seInfo; 21960 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 21961 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 21962 freezer = freezePackage(packageName, "movePackageInternal"); 21963 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 21964 } 21965 21966 final Bundle extras = new Bundle(); 21967 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 21968 extras.putString(Intent.EXTRA_TITLE, label); 21969 mMoveCallbacks.notifyCreated(moveId, extras); 21970 21971 int installFlags; 21972 final boolean moveCompleteApp; 21973 final File measurePath; 21974 21975 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 21976 installFlags = INSTALL_INTERNAL; 21977 moveCompleteApp = !currentAsec; 21978 measurePath = Environment.getDataAppDirectory(volumeUuid); 21979 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 21980 installFlags = INSTALL_EXTERNAL; 21981 moveCompleteApp = false; 21982 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 21983 } else { 21984 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 21985 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 21986 || !volume.isMountedWritable()) { 21987 freezer.close(); 21988 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 21989 "Move location not mounted private volume"); 21990 } 21991 21992 Preconditions.checkState(!currentAsec); 21993 21994 installFlags = INSTALL_INTERNAL; 21995 moveCompleteApp = true; 21996 measurePath = Environment.getDataAppDirectory(volumeUuid); 21997 } 21998 21999 final PackageStats stats = new PackageStats(null, -1); 22000 synchronized (mInstaller) { 22001 for (int userId : installedUserIds) { 22002 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 22003 freezer.close(); 22004 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22005 "Failed to measure package size"); 22006 } 22007 } 22008 } 22009 22010 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 22011 + stats.dataSize); 22012 22013 final long startFreeBytes = measurePath.getFreeSpace(); 22014 final long sizeBytes; 22015 if (moveCompleteApp) { 22016 sizeBytes = stats.codeSize + stats.dataSize; 22017 } else { 22018 sizeBytes = stats.codeSize; 22019 } 22020 22021 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 22022 freezer.close(); 22023 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22024 "Not enough free space to move"); 22025 } 22026 22027 mMoveCallbacks.notifyStatusChanged(moveId, 10); 22028 22029 final CountDownLatch installedLatch = new CountDownLatch(1); 22030 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 22031 @Override 22032 public void onUserActionRequired(Intent intent) throws RemoteException { 22033 throw new IllegalStateException(); 22034 } 22035 22036 @Override 22037 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 22038 Bundle extras) throws RemoteException { 22039 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 22040 + PackageManager.installStatusToString(returnCode, msg)); 22041 22042 installedLatch.countDown(); 22043 freezer.close(); 22044 22045 final int status = PackageManager.installStatusToPublicStatus(returnCode); 22046 switch (status) { 22047 case PackageInstaller.STATUS_SUCCESS: 22048 mMoveCallbacks.notifyStatusChanged(moveId, 22049 PackageManager.MOVE_SUCCEEDED); 22050 break; 22051 case PackageInstaller.STATUS_FAILURE_STORAGE: 22052 mMoveCallbacks.notifyStatusChanged(moveId, 22053 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 22054 break; 22055 default: 22056 mMoveCallbacks.notifyStatusChanged(moveId, 22057 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 22058 break; 22059 } 22060 } 22061 }; 22062 22063 final MoveInfo move; 22064 if (moveCompleteApp) { 22065 // Kick off a thread to report progress estimates 22066 new Thread() { 22067 @Override 22068 public void run() { 22069 while (true) { 22070 try { 22071 if (installedLatch.await(1, TimeUnit.SECONDS)) { 22072 break; 22073 } 22074 } catch (InterruptedException ignored) { 22075 } 22076 22077 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 22078 final int progress = 10 + (int) MathUtils.constrain( 22079 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 22080 mMoveCallbacks.notifyStatusChanged(moveId, progress); 22081 } 22082 } 22083 }.start(); 22084 22085 final String dataAppName = codeFile.getName(); 22086 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 22087 dataAppName, appId, seinfo, targetSdkVersion); 22088 } else { 22089 move = null; 22090 } 22091 22092 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 22093 22094 final Message msg = mHandler.obtainMessage(INIT_COPY); 22095 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 22096 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 22097 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 22098 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/, 22099 PackageManager.INSTALL_REASON_UNKNOWN); 22100 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 22101 msg.obj = params; 22102 22103 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 22104 System.identityHashCode(msg.obj)); 22105 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 22106 System.identityHashCode(msg.obj)); 22107 22108 mHandler.sendMessage(msg); 22109 } 22110 22111 @Override 22112 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 22113 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 22114 22115 final int realMoveId = mNextMoveId.getAndIncrement(); 22116 final Bundle extras = new Bundle(); 22117 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 22118 mMoveCallbacks.notifyCreated(realMoveId, extras); 22119 22120 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 22121 @Override 22122 public void onCreated(int moveId, Bundle extras) { 22123 // Ignored 22124 } 22125 22126 @Override 22127 public void onStatusChanged(int moveId, int status, long estMillis) { 22128 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 22129 } 22130 }; 22131 22132 final StorageManager storage = mContext.getSystemService(StorageManager.class); 22133 storage.setPrimaryStorageUuid(volumeUuid, callback); 22134 return realMoveId; 22135 } 22136 22137 @Override 22138 public int getMoveStatus(int moveId) { 22139 mContext.enforceCallingOrSelfPermission( 22140 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22141 return mMoveCallbacks.mLastStatus.get(moveId); 22142 } 22143 22144 @Override 22145 public void registerMoveCallback(IPackageMoveObserver callback) { 22146 mContext.enforceCallingOrSelfPermission( 22147 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22148 mMoveCallbacks.register(callback); 22149 } 22150 22151 @Override 22152 public void unregisterMoveCallback(IPackageMoveObserver callback) { 22153 mContext.enforceCallingOrSelfPermission( 22154 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22155 mMoveCallbacks.unregister(callback); 22156 } 22157 22158 @Override 22159 public boolean setInstallLocation(int loc) { 22160 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 22161 null); 22162 if (getInstallLocation() == loc) { 22163 return true; 22164 } 22165 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 22166 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 22167 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 22168 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 22169 return true; 22170 } 22171 return false; 22172 } 22173 22174 @Override 22175 public int getInstallLocation() { 22176 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 22177 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 22178 PackageHelper.APP_INSTALL_AUTO); 22179 } 22180 22181 /** Called by UserManagerService */ 22182 void cleanUpUser(UserManagerService userManager, int userHandle) { 22183 synchronized (mPackages) { 22184 mDirtyUsers.remove(userHandle); 22185 mUserNeedsBadging.delete(userHandle); 22186 mSettings.removeUserLPw(userHandle); 22187 mPendingBroadcasts.remove(userHandle); 22188 mInstantAppRegistry.onUserRemovedLPw(userHandle); 22189 removeUnusedPackagesLPw(userManager, userHandle); 22190 } 22191 } 22192 22193 /** 22194 * We're removing userHandle and would like to remove any downloaded packages 22195 * that are no longer in use by any other user. 22196 * @param userHandle the user being removed 22197 */ 22198 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 22199 final boolean DEBUG_CLEAN_APKS = false; 22200 int [] users = userManager.getUserIds(); 22201 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 22202 while (psit.hasNext()) { 22203 PackageSetting ps = psit.next(); 22204 if (ps.pkg == null) { 22205 continue; 22206 } 22207 final String packageName = ps.pkg.packageName; 22208 // Skip over if system app 22209 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 22210 continue; 22211 } 22212 if (DEBUG_CLEAN_APKS) { 22213 Slog.i(TAG, "Checking package " + packageName); 22214 } 22215 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 22216 if (keep) { 22217 if (DEBUG_CLEAN_APKS) { 22218 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 22219 } 22220 } else { 22221 for (int i = 0; i < users.length; i++) { 22222 if (users[i] != userHandle && ps.getInstalled(users[i])) { 22223 keep = true; 22224 if (DEBUG_CLEAN_APKS) { 22225 Slog.i(TAG, " Keeping package " + packageName + " for user " 22226 + users[i]); 22227 } 22228 break; 22229 } 22230 } 22231 } 22232 if (!keep) { 22233 if (DEBUG_CLEAN_APKS) { 22234 Slog.i(TAG, " Removing package " + packageName); 22235 } 22236 mHandler.post(new Runnable() { 22237 public void run() { 22238 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, 22239 userHandle, 0); 22240 } //end run 22241 }); 22242 } 22243 } 22244 } 22245 22246 /** Called by UserManagerService */ 22247 void createNewUser(int userId, String[] disallowedPackages) { 22248 synchronized (mInstallLock) { 22249 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages); 22250 } 22251 synchronized (mPackages) { 22252 scheduleWritePackageRestrictionsLocked(userId); 22253 scheduleWritePackageListLocked(userId); 22254 applyFactoryDefaultBrowserLPw(userId); 22255 primeDomainVerificationsLPw(userId); 22256 } 22257 } 22258 22259 void onNewUserCreated(final int userId) { 22260 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 22261 // If permission review for legacy apps is required, we represent 22262 // dagerous permissions for such apps as always granted runtime 22263 // permissions to keep per user flag state whether review is needed. 22264 // Hence, if a new user is added we have to propagate dangerous 22265 // permission grants for these legacy apps. 22266 if (mPermissionReviewRequired) { 22267 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 22268 | UPDATE_PERMISSIONS_REPLACE_ALL); 22269 } 22270 } 22271 22272 @Override 22273 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 22274 mContext.enforceCallingOrSelfPermission( 22275 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 22276 "Only package verification agents can read the verifier device identity"); 22277 22278 synchronized (mPackages) { 22279 return mSettings.getVerifierDeviceIdentityLPw(); 22280 } 22281 } 22282 22283 @Override 22284 public void setPermissionEnforced(String permission, boolean enforced) { 22285 // TODO: Now that we no longer change GID for storage, this should to away. 22286 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 22287 "setPermissionEnforced"); 22288 if (READ_EXTERNAL_STORAGE.equals(permission)) { 22289 synchronized (mPackages) { 22290 if (mSettings.mReadExternalStorageEnforced == null 22291 || mSettings.mReadExternalStorageEnforced != enforced) { 22292 mSettings.mReadExternalStorageEnforced = enforced; 22293 mSettings.writeLPr(); 22294 } 22295 } 22296 // kill any non-foreground processes so we restart them and 22297 // grant/revoke the GID. 22298 final IActivityManager am = ActivityManager.getService(); 22299 if (am != null) { 22300 final long token = Binder.clearCallingIdentity(); 22301 try { 22302 am.killProcessesBelowForeground("setPermissionEnforcement"); 22303 } catch (RemoteException e) { 22304 } finally { 22305 Binder.restoreCallingIdentity(token); 22306 } 22307 } 22308 } else { 22309 throw new IllegalArgumentException("No selective enforcement for " + permission); 22310 } 22311 } 22312 22313 @Override 22314 @Deprecated 22315 public boolean isPermissionEnforced(String permission) { 22316 return true; 22317 } 22318 22319 @Override 22320 public boolean isStorageLow() { 22321 final long token = Binder.clearCallingIdentity(); 22322 try { 22323 final DeviceStorageMonitorInternal 22324 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 22325 if (dsm != null) { 22326 return dsm.isMemoryLow(); 22327 } else { 22328 return false; 22329 } 22330 } finally { 22331 Binder.restoreCallingIdentity(token); 22332 } 22333 } 22334 22335 @Override 22336 public IPackageInstaller getPackageInstaller() { 22337 return mInstallerService; 22338 } 22339 22340 private boolean userNeedsBadging(int userId) { 22341 int index = mUserNeedsBadging.indexOfKey(userId); 22342 if (index < 0) { 22343 final UserInfo userInfo; 22344 final long token = Binder.clearCallingIdentity(); 22345 try { 22346 userInfo = sUserManager.getUserInfo(userId); 22347 } finally { 22348 Binder.restoreCallingIdentity(token); 22349 } 22350 final boolean b; 22351 if (userInfo != null && userInfo.isManagedProfile()) { 22352 b = true; 22353 } else { 22354 b = false; 22355 } 22356 mUserNeedsBadging.put(userId, b); 22357 return b; 22358 } 22359 return mUserNeedsBadging.valueAt(index); 22360 } 22361 22362 @Override 22363 public KeySet getKeySetByAlias(String packageName, String alias) { 22364 if (packageName == null || alias == null) { 22365 return null; 22366 } 22367 synchronized(mPackages) { 22368 final PackageParser.Package pkg = mPackages.get(packageName); 22369 if (pkg == null) { 22370 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22371 throw new IllegalArgumentException("Unknown package: " + packageName); 22372 } 22373 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22374 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 22375 } 22376 } 22377 22378 @Override 22379 public KeySet getSigningKeySet(String packageName) { 22380 if (packageName == null) { 22381 return null; 22382 } 22383 synchronized(mPackages) { 22384 final PackageParser.Package pkg = mPackages.get(packageName); 22385 if (pkg == null) { 22386 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22387 throw new IllegalArgumentException("Unknown package: " + packageName); 22388 } 22389 if (pkg.applicationInfo.uid != Binder.getCallingUid() 22390 && Process.SYSTEM_UID != Binder.getCallingUid()) { 22391 throw new SecurityException("May not access signing KeySet of other apps."); 22392 } 22393 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22394 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 22395 } 22396 } 22397 22398 @Override 22399 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 22400 if (packageName == null || ks == null) { 22401 return false; 22402 } 22403 synchronized(mPackages) { 22404 final PackageParser.Package pkg = mPackages.get(packageName); 22405 if (pkg == null) { 22406 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22407 throw new IllegalArgumentException("Unknown package: " + packageName); 22408 } 22409 IBinder ksh = ks.getToken(); 22410 if (ksh instanceof KeySetHandle) { 22411 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22412 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 22413 } 22414 return false; 22415 } 22416 } 22417 22418 @Override 22419 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 22420 if (packageName == null || ks == null) { 22421 return false; 22422 } 22423 synchronized(mPackages) { 22424 final PackageParser.Package pkg = mPackages.get(packageName); 22425 if (pkg == null) { 22426 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22427 throw new IllegalArgumentException("Unknown package: " + packageName); 22428 } 22429 IBinder ksh = ks.getToken(); 22430 if (ksh instanceof KeySetHandle) { 22431 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22432 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 22433 } 22434 return false; 22435 } 22436 } 22437 22438 private void deletePackageIfUnusedLPr(final String packageName) { 22439 PackageSetting ps = mSettings.mPackages.get(packageName); 22440 if (ps == null) { 22441 return; 22442 } 22443 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 22444 // TODO Implement atomic delete if package is unused 22445 // It is currently possible that the package will be deleted even if it is installed 22446 // after this method returns. 22447 mHandler.post(new Runnable() { 22448 public void run() { 22449 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, 22450 0, PackageManager.DELETE_ALL_USERS); 22451 } 22452 }); 22453 } 22454 } 22455 22456 /** 22457 * Check and throw if the given before/after packages would be considered a 22458 * downgrade. 22459 */ 22460 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 22461 throws PackageManagerException { 22462 if (after.versionCode < before.mVersionCode) { 22463 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22464 "Update version code " + after.versionCode + " is older than current " 22465 + before.mVersionCode); 22466 } else if (after.versionCode == before.mVersionCode) { 22467 if (after.baseRevisionCode < before.baseRevisionCode) { 22468 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22469 "Update base revision code " + after.baseRevisionCode 22470 + " is older than current " + before.baseRevisionCode); 22471 } 22472 22473 if (!ArrayUtils.isEmpty(after.splitNames)) { 22474 for (int i = 0; i < after.splitNames.length; i++) { 22475 final String splitName = after.splitNames[i]; 22476 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 22477 if (j != -1) { 22478 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 22479 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22480 "Update split " + splitName + " revision code " 22481 + after.splitRevisionCodes[i] + " is older than current " 22482 + before.splitRevisionCodes[j]); 22483 } 22484 } 22485 } 22486 } 22487 } 22488 } 22489 22490 private static class MoveCallbacks extends Handler { 22491 private static final int MSG_CREATED = 1; 22492 private static final int MSG_STATUS_CHANGED = 2; 22493 22494 private final RemoteCallbackList<IPackageMoveObserver> 22495 mCallbacks = new RemoteCallbackList<>(); 22496 22497 private final SparseIntArray mLastStatus = new SparseIntArray(); 22498 22499 public MoveCallbacks(Looper looper) { 22500 super(looper); 22501 } 22502 22503 public void register(IPackageMoveObserver callback) { 22504 mCallbacks.register(callback); 22505 } 22506 22507 public void unregister(IPackageMoveObserver callback) { 22508 mCallbacks.unregister(callback); 22509 } 22510 22511 @Override 22512 public void handleMessage(Message msg) { 22513 final SomeArgs args = (SomeArgs) msg.obj; 22514 final int n = mCallbacks.beginBroadcast(); 22515 for (int i = 0; i < n; i++) { 22516 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 22517 try { 22518 invokeCallback(callback, msg.what, args); 22519 } catch (RemoteException ignored) { 22520 } 22521 } 22522 mCallbacks.finishBroadcast(); 22523 args.recycle(); 22524 } 22525 22526 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 22527 throws RemoteException { 22528 switch (what) { 22529 case MSG_CREATED: { 22530 callback.onCreated(args.argi1, (Bundle) args.arg2); 22531 break; 22532 } 22533 case MSG_STATUS_CHANGED: { 22534 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 22535 break; 22536 } 22537 } 22538 } 22539 22540 private void notifyCreated(int moveId, Bundle extras) { 22541 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 22542 22543 final SomeArgs args = SomeArgs.obtain(); 22544 args.argi1 = moveId; 22545 args.arg2 = extras; 22546 obtainMessage(MSG_CREATED, args).sendToTarget(); 22547 } 22548 22549 private void notifyStatusChanged(int moveId, int status) { 22550 notifyStatusChanged(moveId, status, -1); 22551 } 22552 22553 private void notifyStatusChanged(int moveId, int status, long estMillis) { 22554 Slog.v(TAG, "Move " + moveId + " status " + status); 22555 22556 final SomeArgs args = SomeArgs.obtain(); 22557 args.argi1 = moveId; 22558 args.argi2 = status; 22559 args.arg3 = estMillis; 22560 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 22561 22562 synchronized (mLastStatus) { 22563 mLastStatus.put(moveId, status); 22564 } 22565 } 22566 } 22567 22568 private final static class OnPermissionChangeListeners extends Handler { 22569 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 22570 22571 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 22572 new RemoteCallbackList<>(); 22573 22574 public OnPermissionChangeListeners(Looper looper) { 22575 super(looper); 22576 } 22577 22578 @Override 22579 public void handleMessage(Message msg) { 22580 switch (msg.what) { 22581 case MSG_ON_PERMISSIONS_CHANGED: { 22582 final int uid = msg.arg1; 22583 handleOnPermissionsChanged(uid); 22584 } break; 22585 } 22586 } 22587 22588 public void addListenerLocked(IOnPermissionsChangeListener listener) { 22589 mPermissionListeners.register(listener); 22590 22591 } 22592 22593 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 22594 mPermissionListeners.unregister(listener); 22595 } 22596 22597 public void onPermissionsChanged(int uid) { 22598 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 22599 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 22600 } 22601 } 22602 22603 private void handleOnPermissionsChanged(int uid) { 22604 final int count = mPermissionListeners.beginBroadcast(); 22605 try { 22606 for (int i = 0; i < count; i++) { 22607 IOnPermissionsChangeListener callback = mPermissionListeners 22608 .getBroadcastItem(i); 22609 try { 22610 callback.onPermissionsChanged(uid); 22611 } catch (RemoteException e) { 22612 Log.e(TAG, "Permission listener is dead", e); 22613 } 22614 } 22615 } finally { 22616 mPermissionListeners.finishBroadcast(); 22617 } 22618 } 22619 } 22620 22621 private class PackageManagerInternalImpl extends PackageManagerInternal { 22622 @Override 22623 public void setLocationPackagesProvider(PackagesProvider provider) { 22624 synchronized (mPackages) { 22625 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 22626 } 22627 } 22628 22629 @Override 22630 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 22631 synchronized (mPackages) { 22632 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 22633 } 22634 } 22635 22636 @Override 22637 public void setSmsAppPackagesProvider(PackagesProvider provider) { 22638 synchronized (mPackages) { 22639 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 22640 } 22641 } 22642 22643 @Override 22644 public void setDialerAppPackagesProvider(PackagesProvider provider) { 22645 synchronized (mPackages) { 22646 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 22647 } 22648 } 22649 22650 @Override 22651 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 22652 synchronized (mPackages) { 22653 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 22654 } 22655 } 22656 22657 @Override 22658 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 22659 synchronized (mPackages) { 22660 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 22661 } 22662 } 22663 22664 @Override 22665 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 22666 synchronized (mPackages) { 22667 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 22668 packageName, userId); 22669 } 22670 } 22671 22672 @Override 22673 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 22674 synchronized (mPackages) { 22675 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 22676 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 22677 packageName, userId); 22678 } 22679 } 22680 22681 @Override 22682 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 22683 synchronized (mPackages) { 22684 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 22685 packageName, userId); 22686 } 22687 } 22688 22689 @Override 22690 public void setKeepUninstalledPackages(final List<String> packageList) { 22691 Preconditions.checkNotNull(packageList); 22692 List<String> removedFromList = null; 22693 synchronized (mPackages) { 22694 if (mKeepUninstalledPackages != null) { 22695 final int packagesCount = mKeepUninstalledPackages.size(); 22696 for (int i = 0; i < packagesCount; i++) { 22697 String oldPackage = mKeepUninstalledPackages.get(i); 22698 if (packageList != null && packageList.contains(oldPackage)) { 22699 continue; 22700 } 22701 if (removedFromList == null) { 22702 removedFromList = new ArrayList<>(); 22703 } 22704 removedFromList.add(oldPackage); 22705 } 22706 } 22707 mKeepUninstalledPackages = new ArrayList<>(packageList); 22708 if (removedFromList != null) { 22709 final int removedCount = removedFromList.size(); 22710 for (int i = 0; i < removedCount; i++) { 22711 deletePackageIfUnusedLPr(removedFromList.get(i)); 22712 } 22713 } 22714 } 22715 } 22716 22717 @Override 22718 public boolean isPermissionsReviewRequired(String packageName, int userId) { 22719 synchronized (mPackages) { 22720 // If we do not support permission review, done. 22721 if (!mPermissionReviewRequired) { 22722 return false; 22723 } 22724 22725 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 22726 if (packageSetting == null) { 22727 return false; 22728 } 22729 22730 // Permission review applies only to apps not supporting the new permission model. 22731 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 22732 return false; 22733 } 22734 22735 // Legacy apps have the permission and get user consent on launch. 22736 PermissionsState permissionsState = packageSetting.getPermissionsState(); 22737 return permissionsState.isPermissionReviewRequired(userId); 22738 } 22739 } 22740 22741 @Override 22742 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 22743 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 22744 } 22745 22746 @Override 22747 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 22748 int userId) { 22749 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 22750 } 22751 22752 @Override 22753 public void setDeviceAndProfileOwnerPackages( 22754 int deviceOwnerUserId, String deviceOwnerPackage, 22755 SparseArray<String> profileOwnerPackages) { 22756 mProtectedPackages.setDeviceAndProfileOwnerPackages( 22757 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 22758 } 22759 22760 @Override 22761 public boolean isPackageDataProtected(int userId, String packageName) { 22762 return mProtectedPackages.isPackageDataProtected(userId, packageName); 22763 } 22764 22765 @Override 22766 public boolean isPackageEphemeral(int userId, String packageName) { 22767 synchronized (mPackages) { 22768 final PackageSetting ps = mSettings.mPackages.get(packageName); 22769 return ps != null ? ps.getInstantApp(userId) : false; 22770 } 22771 } 22772 22773 @Override 22774 public boolean wasPackageEverLaunched(String packageName, int userId) { 22775 synchronized (mPackages) { 22776 return mSettings.wasPackageEverLaunchedLPr(packageName, userId); 22777 } 22778 } 22779 22780 @Override 22781 public void grantRuntimePermission(String packageName, String name, int userId, 22782 boolean overridePolicy) { 22783 PackageManagerService.this.grantRuntimePermission(packageName, name, userId, 22784 overridePolicy); 22785 } 22786 22787 @Override 22788 public void revokeRuntimePermission(String packageName, String name, int userId, 22789 boolean overridePolicy) { 22790 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId, 22791 overridePolicy); 22792 } 22793 22794 @Override 22795 public String getNameForUid(int uid) { 22796 return PackageManagerService.this.getNameForUid(uid); 22797 } 22798 22799 @Override 22800 public void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj, 22801 Intent origIntent, String resolvedType, Intent launchIntent, 22802 String callingPackage, int userId) { 22803 PackageManagerService.this.requestEphemeralResolutionPhaseTwo( 22804 responseObj, origIntent, resolvedType, launchIntent, callingPackage, userId); 22805 } 22806 22807 @Override 22808 public void grantEphemeralAccess(int userId, Intent intent, 22809 int targetAppId, int ephemeralAppId) { 22810 synchronized (mPackages) { 22811 mInstantAppRegistry.grantInstantAccessLPw(userId, intent, 22812 targetAppId, ephemeralAppId); 22813 } 22814 } 22815 22816 @Override 22817 public void pruneInstantApps() { 22818 synchronized (mPackages) { 22819 mInstantAppRegistry.pruneInstantAppsLPw(); 22820 } 22821 } 22822 22823 @Override 22824 public String getSetupWizardPackageName() { 22825 return mSetupWizardPackage; 22826 } 22827 22828 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) { 22829 if (policy != null) { 22830 mExternalSourcesPolicy = policy; 22831 } 22832 } 22833 22834 @Override 22835 public boolean isPackagePersistent(String packageName) { 22836 synchronized (mPackages) { 22837 PackageParser.Package pkg = mPackages.get(packageName); 22838 return pkg != null 22839 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM 22840 | ApplicationInfo.FLAG_PERSISTENT)) == 22841 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT)) 22842 : false; 22843 } 22844 } 22845 22846 @Override 22847 public List<PackageInfo> getOverlayPackages(int userId) { 22848 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>(); 22849 synchronized (mPackages) { 22850 for (PackageParser.Package p : mPackages.values()) { 22851 if (p.mOverlayTarget != null) { 22852 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId); 22853 if (pkg != null) { 22854 overlayPackages.add(pkg); 22855 } 22856 } 22857 } 22858 } 22859 return overlayPackages; 22860 } 22861 22862 @Override 22863 public List<String> getTargetPackageNames(int userId) { 22864 List<String> targetPackages = new ArrayList<>(); 22865 synchronized (mPackages) { 22866 for (PackageParser.Package p : mPackages.values()) { 22867 if (p.mOverlayTarget == null) { 22868 targetPackages.add(p.packageName); 22869 } 22870 } 22871 } 22872 return targetPackages; 22873 } 22874 22875 22876 @Override 22877 public boolean setEnabledOverlayPackages(int userId, String targetPackageName, 22878 List<String> overlayPackageNames) { 22879 // TODO: implement when we integrate OMS properly 22880 return false; 22881 } 22882 } 22883 22884 @Override 22885 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 22886 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 22887 synchronized (mPackages) { 22888 final long identity = Binder.clearCallingIdentity(); 22889 try { 22890 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 22891 packageNames, userId); 22892 } finally { 22893 Binder.restoreCallingIdentity(identity); 22894 } 22895 } 22896 } 22897 22898 @Override 22899 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) { 22900 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices"); 22901 synchronized (mPackages) { 22902 final long identity = Binder.clearCallingIdentity(); 22903 try { 22904 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr( 22905 packageNames, userId); 22906 } finally { 22907 Binder.restoreCallingIdentity(identity); 22908 } 22909 } 22910 } 22911 22912 private static void enforceSystemOrPhoneCaller(String tag) { 22913 int callingUid = Binder.getCallingUid(); 22914 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 22915 throw new SecurityException( 22916 "Cannot call " + tag + " from UID " + callingUid); 22917 } 22918 } 22919 22920 boolean isHistoricalPackageUsageAvailable() { 22921 return mPackageUsage.isHistoricalPackageUsageAvailable(); 22922 } 22923 22924 /** 22925 * Return a <b>copy</b> of the collection of packages known to the package manager. 22926 * @return A copy of the values of mPackages. 22927 */ 22928 Collection<PackageParser.Package> getPackages() { 22929 synchronized (mPackages) { 22930 return new ArrayList<>(mPackages.values()); 22931 } 22932 } 22933 22934 /** 22935 * Logs process start information (including base APK hash) to the security log. 22936 * @hide 22937 */ 22938 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 22939 String apkFile, int pid) { 22940 if (!SecurityLog.isLoggingEnabled()) { 22941 return; 22942 } 22943 Bundle data = new Bundle(); 22944 data.putLong("startTimestamp", System.currentTimeMillis()); 22945 data.putString("processName", processName); 22946 data.putInt("uid", uid); 22947 data.putString("seinfo", seinfo); 22948 data.putString("apkFile", apkFile); 22949 data.putInt("pid", pid); 22950 Message msg = mProcessLoggingHandler.obtainMessage( 22951 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 22952 msg.setData(data); 22953 mProcessLoggingHandler.sendMessage(msg); 22954 } 22955 22956 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 22957 return mCompilerStats.getPackageStats(pkgName); 22958 } 22959 22960 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 22961 return getOrCreateCompilerPackageStats(pkg.packageName); 22962 } 22963 22964 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 22965 return mCompilerStats.getOrCreatePackageStats(pkgName); 22966 } 22967 22968 public void deleteCompilerPackageStats(String pkgName) { 22969 mCompilerStats.deletePackageStats(pkgName); 22970 } 22971 22972 @Override 22973 public int getInstallReason(String packageName, int userId) { 22974 enforceCrossUserPermission(Binder.getCallingUid(), userId, 22975 true /* requireFullPermission */, false /* checkShell */, 22976 "get install reason"); 22977 synchronized (mPackages) { 22978 final PackageSetting ps = mSettings.mPackages.get(packageName); 22979 if (ps != null) { 22980 return ps.getInstallReason(userId); 22981 } 22982 } 22983 return PackageManager.INSTALL_REASON_UNKNOWN; 22984 } 22985 22986 @Override 22987 public boolean canRequestPackageInstalls(String packageName, int userId) { 22988 int callingUid = Binder.getCallingUid(); 22989 int uid = getPackageUid(packageName, 0, userId); 22990 if (callingUid != uid && callingUid != Process.ROOT_UID 22991 && callingUid != Process.SYSTEM_UID) { 22992 throw new SecurityException( 22993 "Caller uid " + callingUid + " does not own package " + packageName); 22994 } 22995 ApplicationInfo info = getApplicationInfo(packageName, 0, userId); 22996 if (info == null) { 22997 return false; 22998 } 22999 if (info.targetSdkVersion < Build.VERSION_CODES.O) { 23000 throw new UnsupportedOperationException( 23001 "Operation only supported on apps targeting Android O or higher"); 23002 } 23003 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES; 23004 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission); 23005 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) { 23006 throw new SecurityException("Need to declare " + appOpPermission + " to call this api"); 23007 } 23008 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) { 23009 return false; 23010 } 23011 if (mExternalSourcesPolicy != null) { 23012 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid); 23013 if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) { 23014 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED; 23015 } 23016 } 23017 return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED; 23018 } 23019} 23020