PackageManagerService.java revision bc9caa1a2a38e23f7a6b61bcda81b5759e45ec66
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.ChangedPackages; 130import android.content.pm.ComponentInfo; 131import android.content.pm.InstantAppRequest; 132import android.content.pm.AuxiliaryResolveInfo; 133import android.content.pm.FallbackCategoryProvider; 134import android.content.pm.FeatureInfo; 135import android.content.pm.IOnPermissionsChangeListener; 136import android.content.pm.IPackageDataObserver; 137import android.content.pm.IPackageDeleteObserver; 138import android.content.pm.IPackageDeleteObserver2; 139import android.content.pm.IPackageInstallObserver2; 140import android.content.pm.IPackageInstaller; 141import android.content.pm.IPackageManager; 142import android.content.pm.IPackageMoveObserver; 143import android.content.pm.IPackageStatsObserver; 144import android.content.pm.InstantAppInfo; 145import android.content.pm.InstantAppResolveInfo; 146import android.content.pm.InstrumentationInfo; 147import android.content.pm.IntentFilterVerificationInfo; 148import android.content.pm.KeySet; 149import android.content.pm.PackageCleanItem; 150import android.content.pm.PackageInfo; 151import android.content.pm.PackageInfoLite; 152import android.content.pm.PackageInstaller; 153import android.content.pm.PackageManager; 154import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 155import android.content.pm.PackageManagerInternal; 156import android.content.pm.PackageParser; 157import android.content.pm.PackageParser.ActivityIntentInfo; 158import android.content.pm.PackageParser.PackageLite; 159import android.content.pm.PackageParser.PackageParserException; 160import android.content.pm.PackageStats; 161import android.content.pm.PackageUserState; 162import android.content.pm.ParceledListSlice; 163import android.content.pm.PermissionGroupInfo; 164import android.content.pm.PermissionInfo; 165import android.content.pm.ProviderInfo; 166import android.content.pm.ResolveInfo; 167import android.content.pm.SELinuxUtil; 168import android.content.pm.ServiceInfo; 169import android.content.pm.SharedLibraryInfo; 170import android.content.pm.Signature; 171import android.content.pm.UserInfo; 172import android.content.pm.VerifierDeviceIdentity; 173import android.content.pm.VerifierInfo; 174import android.content.pm.VersionedPackage; 175import android.content.res.Resources; 176import android.graphics.Bitmap; 177import android.hardware.display.DisplayManager; 178import android.net.Uri; 179import android.os.Binder; 180import android.os.Build; 181import android.os.Bundle; 182import android.os.Debug; 183import android.os.Environment; 184import android.os.Environment.UserEnvironment; 185import android.os.FileUtils; 186import android.os.Handler; 187import android.os.IBinder; 188import android.os.Looper; 189import android.os.Message; 190import android.os.Parcel; 191import android.os.ParcelFileDescriptor; 192import android.os.PatternMatcher; 193import android.os.Process; 194import android.os.RemoteCallbackList; 195import android.os.RemoteException; 196import android.os.ResultReceiver; 197import android.os.SELinux; 198import android.os.ServiceManager; 199import android.os.ShellCallback; 200import android.os.SystemClock; 201import android.os.SystemProperties; 202import android.os.Trace; 203import android.os.UserHandle; 204import android.os.UserManager; 205import android.os.UserManagerInternal; 206import android.os.storage.IStorageManager; 207import android.os.storage.StorageEventListener; 208import android.os.storage.StorageManager; 209import android.os.storage.StorageManagerInternal; 210import android.os.storage.VolumeInfo; 211import android.os.storage.VolumeRecord; 212import android.provider.Settings.Global; 213import android.provider.Settings.Secure; 214import android.security.KeyStore; 215import android.security.SystemKeyStore; 216import android.service.pm.PackageServiceDumpProto; 217import android.system.ErrnoException; 218import android.system.Os; 219import android.text.TextUtils; 220import android.text.format.DateUtils; 221import android.util.ArrayMap; 222import android.util.ArraySet; 223import android.util.Base64; 224import android.util.DisplayMetrics; 225import android.util.EventLog; 226import android.util.ExceptionUtils; 227import android.util.Log; 228import android.util.LogPrinter; 229import android.util.MathUtils; 230import android.util.PackageUtils; 231import android.util.Pair; 232import android.util.PrintStreamPrinter; 233import android.util.Slog; 234import android.util.SparseArray; 235import android.util.SparseBooleanArray; 236import android.util.SparseIntArray; 237import android.util.Xml; 238import android.util.jar.StrictJarFile; 239import android.util.proto.ProtoOutputStream; 240import android.view.Display; 241 242import com.android.internal.R; 243import com.android.internal.annotations.GuardedBy; 244import com.android.internal.app.IMediaContainerService; 245import com.android.internal.app.ResolverActivity; 246import com.android.internal.content.NativeLibraryHelper; 247import com.android.internal.content.PackageHelper; 248import com.android.internal.logging.MetricsLogger; 249import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 250import com.android.internal.os.IParcelFileDescriptorFactory; 251import com.android.internal.os.RoSystemProperties; 252import com.android.internal.os.SomeArgs; 253import com.android.internal.os.Zygote; 254import com.android.internal.telephony.CarrierAppUtils; 255import com.android.internal.util.ArrayUtils; 256import com.android.internal.util.ConcurrentUtils; 257import com.android.internal.util.FastPrintWriter; 258import com.android.internal.util.FastXmlSerializer; 259import com.android.internal.util.IndentingPrintWriter; 260import com.android.internal.util.Preconditions; 261import com.android.internal.util.XmlUtils; 262import com.android.server.AttributeCache; 263import com.android.server.BackgroundDexOptJobService; 264import com.android.server.DeviceIdleController; 265import com.android.server.EventLogTags; 266import com.android.server.FgThread; 267import com.android.server.IntentResolver; 268import com.android.server.LocalServices; 269import com.android.server.ServiceThread; 270import com.android.server.SystemConfig; 271import com.android.server.SystemServerInitThreadPool; 272import com.android.server.Watchdog; 273import com.android.server.net.NetworkPolicyManagerInternal; 274import com.android.server.pm.Installer.InstallerException; 275import com.android.server.pm.PermissionsState.PermissionState; 276import com.android.server.pm.Settings.DatabaseVersion; 277import com.android.server.pm.Settings.VersionInfo; 278import com.android.server.pm.dex.DexManager; 279import com.android.server.storage.DeviceStorageMonitorInternal; 280 281import dalvik.system.CloseGuard; 282import dalvik.system.DexFile; 283import dalvik.system.VMRuntime; 284 285import libcore.io.IoUtils; 286import libcore.util.EmptyArray; 287 288import org.xmlpull.v1.XmlPullParser; 289import org.xmlpull.v1.XmlPullParserException; 290import org.xmlpull.v1.XmlSerializer; 291 292import java.io.BufferedOutputStream; 293import java.io.BufferedReader; 294import java.io.ByteArrayInputStream; 295import java.io.ByteArrayOutputStream; 296import java.io.File; 297import java.io.FileDescriptor; 298import java.io.FileInputStream; 299import java.io.FileNotFoundException; 300import java.io.FileOutputStream; 301import java.io.FileReader; 302import java.io.FilenameFilter; 303import java.io.IOException; 304import java.io.PrintWriter; 305import java.nio.charset.StandardCharsets; 306import java.security.DigestInputStream; 307import java.security.MessageDigest; 308import java.security.NoSuchAlgorithmException; 309import java.security.PublicKey; 310import java.security.SecureRandom; 311import java.security.cert.Certificate; 312import java.security.cert.CertificateEncodingException; 313import java.security.cert.CertificateException; 314import java.text.SimpleDateFormat; 315import java.util.ArrayList; 316import java.util.Arrays; 317import java.util.Collection; 318import java.util.Collections; 319import java.util.Comparator; 320import java.util.Date; 321import java.util.HashMap; 322import java.util.HashSet; 323import java.util.Iterator; 324import java.util.List; 325import java.util.Map; 326import java.util.Objects; 327import java.util.Set; 328import java.util.concurrent.CountDownLatch; 329import java.util.concurrent.Future; 330import java.util.concurrent.TimeUnit; 331import java.util.concurrent.atomic.AtomicBoolean; 332import java.util.concurrent.atomic.AtomicInteger; 333 334/** 335 * Keep track of all those APKs everywhere. 336 * <p> 337 * Internally there are two important locks: 338 * <ul> 339 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 340 * and other related state. It is a fine-grained lock that should only be held 341 * momentarily, as it's one of the most contended locks in the system. 342 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 343 * operations typically involve heavy lifting of application data on disk. Since 344 * {@code installd} is single-threaded, and it's operations can often be slow, 345 * this lock should never be acquired while already holding {@link #mPackages}. 346 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 347 * holding {@link #mInstallLock}. 348 * </ul> 349 * Many internal methods rely on the caller to hold the appropriate locks, and 350 * this contract is expressed through method name suffixes: 351 * <ul> 352 * <li>fooLI(): the caller must hold {@link #mInstallLock} 353 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 354 * being modified must be frozen 355 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 356 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 357 * </ul> 358 * <p> 359 * Because this class is very central to the platform's security; please run all 360 * CTS and unit tests whenever making modifications: 361 * 362 * <pre> 363 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 364 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases 365 * </pre> 366 */ 367public class PackageManagerService extends IPackageManager.Stub { 368 static final String TAG = "PackageManager"; 369 static final boolean DEBUG_SETTINGS = false; 370 static final boolean DEBUG_PREFERRED = false; 371 static final boolean DEBUG_UPGRADE = false; 372 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 373 private static final boolean DEBUG_BACKUP = false; 374 private static final boolean DEBUG_INSTALL = false; 375 private static final boolean DEBUG_REMOVE = false; 376 private static final boolean DEBUG_BROADCASTS = false; 377 private static final boolean DEBUG_SHOW_INFO = false; 378 private static final boolean DEBUG_PACKAGE_INFO = false; 379 private static final boolean DEBUG_INTENT_MATCHING = false; 380 private static final boolean DEBUG_PACKAGE_SCANNING = false; 381 private static final boolean DEBUG_VERIFY = false; 382 private static final boolean DEBUG_FILTERS = false; 383 384 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 385 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 386 // user, but by default initialize to this. 387 public static final boolean DEBUG_DEXOPT = false; 388 389 private static final boolean DEBUG_ABI_SELECTION = false; 390 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 391 private static final boolean DEBUG_TRIAGED_MISSING = false; 392 private static final boolean DEBUG_APP_DATA = false; 393 394 /** REMOVE. According to Svet, this was only used to reset permissions during development. */ 395 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 396 397 private static final boolean DISABLE_EPHEMERAL_APPS = false; 398 private static final boolean HIDE_EPHEMERAL_APIS = false; 399 400 private static final boolean ENABLE_FREE_CACHE_V2 = 401 SystemProperties.getBoolean("fw.free_cache_v2", false); 402 403 private static final int RADIO_UID = Process.PHONE_UID; 404 private static final int LOG_UID = Process.LOG_UID; 405 private static final int NFC_UID = Process.NFC_UID; 406 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 407 private static final int SHELL_UID = Process.SHELL_UID; 408 409 // Cap the size of permission trees that 3rd party apps can define 410 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 411 412 // Suffix used during package installation when copying/moving 413 // package apks to install directory. 414 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 415 416 static final int SCAN_NO_DEX = 1<<1; 417 static final int SCAN_FORCE_DEX = 1<<2; 418 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 419 static final int SCAN_NEW_INSTALL = 1<<4; 420 static final int SCAN_UPDATE_TIME = 1<<5; 421 static final int SCAN_BOOTING = 1<<6; 422 static final int SCAN_TRUSTED_OVERLAY = 1<<7; 423 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8; 424 static final int SCAN_REPLACING = 1<<9; 425 static final int SCAN_REQUIRE_KNOWN = 1<<10; 426 static final int SCAN_MOVE = 1<<11; 427 static final int SCAN_INITIAL = 1<<12; 428 static final int SCAN_CHECK_ONLY = 1<<13; 429 static final int SCAN_DONT_KILL_APP = 1<<14; 430 static final int SCAN_IGNORE_FROZEN = 1<<15; 431 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16; 432 static final int SCAN_AS_INSTANT_APP = 1<<17; 433 static final int SCAN_AS_FULL_APP = 1<<18; 434 /** Should not be with the scan flags */ 435 static final int FLAGS_REMOVE_CHATTY = 1<<31; 436 437 private static final String STATIC_SHARED_LIB_DELIMITER = "_"; 438 439 private static final int[] EMPTY_INT_ARRAY = new int[0]; 440 441 /** 442 * Timeout (in milliseconds) after which the watchdog should declare that 443 * our handler thread is wedged. The usual default for such things is one 444 * minute but we sometimes do very lengthy I/O operations on this thread, 445 * such as installing multi-gigabyte applications, so ours needs to be longer. 446 */ 447 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 448 449 /** 450 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 451 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 452 * settings entry if available, otherwise we use the hardcoded default. If it's been 453 * more than this long since the last fstrim, we force one during the boot sequence. 454 * 455 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 456 * one gets run at the next available charging+idle time. This final mandatory 457 * no-fstrim check kicks in only of the other scheduling criteria is never met. 458 */ 459 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 460 461 /** 462 * Whether verification is enabled by default. 463 */ 464 private static final boolean DEFAULT_VERIFY_ENABLE = true; 465 466 /** 467 * The default maximum time to wait for the verification agent to return in 468 * milliseconds. 469 */ 470 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 471 472 /** 473 * The default response for package verification timeout. 474 * 475 * This can be either PackageManager.VERIFICATION_ALLOW or 476 * PackageManager.VERIFICATION_REJECT. 477 */ 478 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 479 480 static final String PLATFORM_PACKAGE_NAME = "android"; 481 482 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 483 484 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 485 DEFAULT_CONTAINER_PACKAGE, 486 "com.android.defcontainer.DefaultContainerService"); 487 488 private static final String KILL_APP_REASON_GIDS_CHANGED = 489 "permission grant or revoke changed gids"; 490 491 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 492 "permissions revoked"; 493 494 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 495 496 private static final String PACKAGE_SCHEME = "package"; 497 498 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 499 500 /** Permission grant: not grant the permission. */ 501 private static final int GRANT_DENIED = 1; 502 503 /** Permission grant: grant the permission as an install permission. */ 504 private static final int GRANT_INSTALL = 2; 505 506 /** Permission grant: grant the permission as a runtime one. */ 507 private static final int GRANT_RUNTIME = 3; 508 509 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 510 private static final int GRANT_UPGRADE = 4; 511 512 /** Canonical intent used to identify what counts as a "web browser" app */ 513 private static final Intent sBrowserIntent; 514 static { 515 sBrowserIntent = new Intent(); 516 sBrowserIntent.setAction(Intent.ACTION_VIEW); 517 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 518 sBrowserIntent.setData(Uri.parse("http:")); 519 } 520 521 /** 522 * The set of all protected actions [i.e. those actions for which a high priority 523 * intent filter is disallowed]. 524 */ 525 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 526 static { 527 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 528 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 529 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 530 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 531 } 532 533 // Compilation reasons. 534 public static final int REASON_FIRST_BOOT = 0; 535 public static final int REASON_BOOT = 1; 536 public static final int REASON_INSTALL = 2; 537 public static final int REASON_BACKGROUND_DEXOPT = 3; 538 public static final int REASON_AB_OTA = 4; 539 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 540 public static final int REASON_SHARED_APK = 6; 541 public static final int REASON_FORCED_DEXOPT = 7; 542 public static final int REASON_CORE_APP = 8; 543 544 public static final int REASON_LAST = REASON_CORE_APP; 545 546 /** All dangerous permission names in the same order as the events in MetricsEvent */ 547 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList( 548 Manifest.permission.READ_CALENDAR, 549 Manifest.permission.WRITE_CALENDAR, 550 Manifest.permission.CAMERA, 551 Manifest.permission.READ_CONTACTS, 552 Manifest.permission.WRITE_CONTACTS, 553 Manifest.permission.GET_ACCOUNTS, 554 Manifest.permission.ACCESS_FINE_LOCATION, 555 Manifest.permission.ACCESS_COARSE_LOCATION, 556 Manifest.permission.RECORD_AUDIO, 557 Manifest.permission.READ_PHONE_STATE, 558 Manifest.permission.CALL_PHONE, 559 Manifest.permission.READ_CALL_LOG, 560 Manifest.permission.WRITE_CALL_LOG, 561 Manifest.permission.ADD_VOICEMAIL, 562 Manifest.permission.USE_SIP, 563 Manifest.permission.PROCESS_OUTGOING_CALLS, 564 Manifest.permission.READ_CELL_BROADCASTS, 565 Manifest.permission.BODY_SENSORS, 566 Manifest.permission.SEND_SMS, 567 Manifest.permission.RECEIVE_SMS, 568 Manifest.permission.READ_SMS, 569 Manifest.permission.RECEIVE_WAP_PUSH, 570 Manifest.permission.RECEIVE_MMS, 571 Manifest.permission.READ_EXTERNAL_STORAGE, 572 Manifest.permission.WRITE_EXTERNAL_STORAGE, 573 Manifest.permission.READ_PHONE_NUMBER, 574 Manifest.permission.ANSWER_PHONE_CALLS); 575 576 577 /** 578 * Version number for the package parser cache. Increment this whenever the format or 579 * extent of cached data changes. See {@code PackageParser#setCacheDir}. 580 */ 581 private static final String PACKAGE_PARSER_CACHE_VERSION = "1"; 582 583 /** 584 * Whether the package parser cache is enabled. 585 */ 586 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true; 587 588 final ServiceThread mHandlerThread; 589 590 final PackageHandler mHandler; 591 592 private final ProcessLoggingHandler mProcessLoggingHandler; 593 594 /** 595 * Messages for {@link #mHandler} that need to wait for system ready before 596 * being dispatched. 597 */ 598 private ArrayList<Message> mPostSystemReadyMessages; 599 600 final int mSdkVersion = Build.VERSION.SDK_INT; 601 602 final Context mContext; 603 final boolean mFactoryTest; 604 final boolean mOnlyCore; 605 final DisplayMetrics mMetrics; 606 final int mDefParseFlags; 607 final String[] mSeparateProcesses; 608 final boolean mIsUpgrade; 609 final boolean mIsPreNUpgrade; 610 final boolean mIsPreNMR1Upgrade; 611 612 @GuardedBy("mPackages") 613 private boolean mDexOptDialogShown; 614 615 /** The location for ASEC container files on internal storage. */ 616 final String mAsecInternalPath; 617 618 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 619 // LOCK HELD. Can be called with mInstallLock held. 620 @GuardedBy("mInstallLock") 621 final Installer mInstaller; 622 623 /** Directory where installed third-party apps stored */ 624 final File mAppInstallDir; 625 626 /** 627 * Directory to which applications installed internally have their 628 * 32 bit native libraries copied. 629 */ 630 private File mAppLib32InstallDir; 631 632 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 633 // apps. 634 final File mDrmAppPrivateInstallDir; 635 636 // ---------------------------------------------------------------- 637 638 // Lock for state used when installing and doing other long running 639 // operations. Methods that must be called with this lock held have 640 // the suffix "LI". 641 final Object mInstallLock = new Object(); 642 643 // ---------------------------------------------------------------- 644 645 // Keys are String (package name), values are Package. This also serves 646 // as the lock for the global state. Methods that must be called with 647 // this lock held have the prefix "LP". 648 @GuardedBy("mPackages") 649 final ArrayMap<String, PackageParser.Package> mPackages = 650 new ArrayMap<String, PackageParser.Package>(); 651 652 final ArrayMap<String, Set<String>> mKnownCodebase = 653 new ArrayMap<String, Set<String>>(); 654 655 // List of APK paths to load for each user and package. This data is never 656 // persisted by the package manager. Instead, the overlay manager will 657 // ensure the data is up-to-date in runtime. 658 @GuardedBy("mPackages") 659 final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths = 660 new SparseArray<ArrayMap<String, ArrayList<String>>>(); 661 662 /** 663 * Tracks new system packages [received in an OTA] that we expect to 664 * find updated user-installed versions. Keys are package name, values 665 * are package location. 666 */ 667 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 668 /** 669 * Tracks high priority intent filters for protected actions. During boot, certain 670 * filter actions are protected and should never be allowed to have a high priority 671 * intent filter for them. However, there is one, and only one exception -- the 672 * setup wizard. It must be able to define a high priority intent filter for these 673 * actions to ensure there are no escapes from the wizard. We need to delay processing 674 * of these during boot as we need to look at all of the system packages in order 675 * to know which component is the setup wizard. 676 */ 677 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 678 /** 679 * Whether or not processing protected filters should be deferred. 680 */ 681 private boolean mDeferProtectedFilters = true; 682 683 /** 684 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 685 */ 686 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 687 /** 688 * Whether or not system app permissions should be promoted from install to runtime. 689 */ 690 boolean mPromoteSystemApps; 691 692 @GuardedBy("mPackages") 693 final Settings mSettings; 694 695 /** 696 * Set of package names that are currently "frozen", which means active 697 * surgery is being done on the code/data for that package. The platform 698 * will refuse to launch frozen packages to avoid race conditions. 699 * 700 * @see PackageFreezer 701 */ 702 @GuardedBy("mPackages") 703 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 704 705 final ProtectedPackages mProtectedPackages; 706 707 boolean mFirstBoot; 708 709 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy; 710 711 // System configuration read by SystemConfig. 712 final int[] mGlobalGids; 713 final SparseArray<ArraySet<String>> mSystemPermissions; 714 @GuardedBy("mAvailableFeatures") 715 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 716 717 // If mac_permissions.xml was found for seinfo labeling. 718 boolean mFoundPolicyFile; 719 720 private final InstantAppRegistry mInstantAppRegistry; 721 722 @GuardedBy("mPackages") 723 int mChangedPackagesSequenceNumber; 724 /** 725 * List of changed [installed, removed or updated] packages. 726 * mapping from user id -> sequence number -> package name 727 */ 728 @GuardedBy("mPackages") 729 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>(); 730 /** 731 * The sequence number of the last change to a package. 732 * mapping from user id -> package name -> sequence number 733 */ 734 @GuardedBy("mPackages") 735 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>(); 736 737 final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() { 738 @Override public boolean hasFeature(String feature) { 739 return PackageManagerService.this.hasSystemFeature(feature, 0); 740 } 741 }; 742 743 public static final class SharedLibraryEntry { 744 public final String path; 745 public final String apk; 746 public final SharedLibraryInfo info; 747 748 SharedLibraryEntry(String _path, String _apk, String name, int version, int type, 749 String declaringPackageName, int declaringPackageVersionCode) { 750 path = _path; 751 apk = _apk; 752 info = new SharedLibraryInfo(name, version, type, new VersionedPackage( 753 declaringPackageName, declaringPackageVersionCode), null); 754 } 755 } 756 757 // Currently known shared libraries. 758 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>(); 759 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage = 760 new ArrayMap<>(); 761 762 // All available activities, for your resolving pleasure. 763 final ActivityIntentResolver mActivities = 764 new ActivityIntentResolver(); 765 766 // All available receivers, for your resolving pleasure. 767 final ActivityIntentResolver mReceivers = 768 new ActivityIntentResolver(); 769 770 // All available services, for your resolving pleasure. 771 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 772 773 // All available providers, for your resolving pleasure. 774 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 775 776 // Mapping from provider base names (first directory in content URI codePath) 777 // to the provider information. 778 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 779 new ArrayMap<String, PackageParser.Provider>(); 780 781 // Mapping from instrumentation class names to info about them. 782 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 783 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 784 785 // Mapping from permission names to info about them. 786 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 787 new ArrayMap<String, PackageParser.PermissionGroup>(); 788 789 // Packages whose data we have transfered into another package, thus 790 // should no longer exist. 791 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 792 793 // Broadcast actions that are only available to the system. 794 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 795 796 /** List of packages waiting for verification. */ 797 final SparseArray<PackageVerificationState> mPendingVerification 798 = new SparseArray<PackageVerificationState>(); 799 800 /** Set of packages associated with each app op permission. */ 801 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 802 803 final PackageInstallerService mInstallerService; 804 805 private final PackageDexOptimizer mPackageDexOptimizer; 806 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package 807 // is used by other apps). 808 private final DexManager mDexManager; 809 810 private AtomicInteger mNextMoveId = new AtomicInteger(); 811 private final MoveCallbacks mMoveCallbacks; 812 813 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 814 815 // Cache of users who need badging. 816 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 817 818 /** Token for keys in mPendingVerification. */ 819 private int mPendingVerificationToken = 0; 820 821 volatile boolean mSystemReady; 822 volatile boolean mSafeMode; 823 volatile boolean mHasSystemUidErrors; 824 825 ApplicationInfo mAndroidApplication; 826 final ActivityInfo mResolveActivity = new ActivityInfo(); 827 final ResolveInfo mResolveInfo = new ResolveInfo(); 828 ComponentName mResolveComponentName; 829 PackageParser.Package mPlatformPackage; 830 ComponentName mCustomResolverComponentName; 831 832 boolean mResolverReplaced = false; 833 834 private final @Nullable ComponentName mIntentFilterVerifierComponent; 835 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 836 837 private int mIntentFilterVerificationToken = 0; 838 839 /** The service connection to the ephemeral resolver */ 840 final EphemeralResolverConnection mInstantAppResolverConnection; 841 842 /** Component used to install ephemeral applications */ 843 ComponentName mInstantAppInstallerComponent; 844 final ActivityInfo mInstantAppInstallerActivity = new ActivityInfo(); 845 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo(); 846 847 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 848 = new SparseArray<IntentFilterVerificationState>(); 849 850 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; 851 852 // List of packages names to keep cached, even if they are uninstalled for all users 853 private List<String> mKeepUninstalledPackages; 854 855 private UserManagerInternal mUserManagerInternal; 856 857 private DeviceIdleController.LocalService mDeviceIdleController; 858 859 private File mCacheDir; 860 861 private ArraySet<String> mPrivappPermissionsViolations; 862 863 private Future<?> mPrepareAppDataFuture; 864 865 private static class IFVerificationParams { 866 PackageParser.Package pkg; 867 boolean replacing; 868 int userId; 869 int verifierUid; 870 871 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 872 int _userId, int _verifierUid) { 873 pkg = _pkg; 874 replacing = _replacing; 875 userId = _userId; 876 replacing = _replacing; 877 verifierUid = _verifierUid; 878 } 879 } 880 881 private interface IntentFilterVerifier<T extends IntentFilter> { 882 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 883 T filter, String packageName); 884 void startVerifications(int userId); 885 void receiveVerificationResponse(int verificationId); 886 } 887 888 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 889 private Context mContext; 890 private ComponentName mIntentFilterVerifierComponent; 891 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 892 893 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 894 mContext = context; 895 mIntentFilterVerifierComponent = verifierComponent; 896 } 897 898 private String getDefaultScheme() { 899 return IntentFilter.SCHEME_HTTPS; 900 } 901 902 @Override 903 public void startVerifications(int userId) { 904 // Launch verifications requests 905 int count = mCurrentIntentFilterVerifications.size(); 906 for (int n=0; n<count; n++) { 907 int verificationId = mCurrentIntentFilterVerifications.get(n); 908 final IntentFilterVerificationState ivs = 909 mIntentFilterVerificationStates.get(verificationId); 910 911 String packageName = ivs.getPackageName(); 912 913 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 914 final int filterCount = filters.size(); 915 ArraySet<String> domainsSet = new ArraySet<>(); 916 for (int m=0; m<filterCount; m++) { 917 PackageParser.ActivityIntentInfo filter = filters.get(m); 918 domainsSet.addAll(filter.getHostsList()); 919 } 920 synchronized (mPackages) { 921 if (mSettings.createIntentFilterVerificationIfNeededLPw( 922 packageName, domainsSet) != null) { 923 scheduleWriteSettingsLocked(); 924 } 925 } 926 sendVerificationRequest(userId, verificationId, ivs); 927 } 928 mCurrentIntentFilterVerifications.clear(); 929 } 930 931 private void sendVerificationRequest(int userId, int verificationId, 932 IntentFilterVerificationState ivs) { 933 934 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 935 verificationIntent.putExtra( 936 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 937 verificationId); 938 verificationIntent.putExtra( 939 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 940 getDefaultScheme()); 941 verificationIntent.putExtra( 942 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 943 ivs.getHostsString()); 944 verificationIntent.putExtra( 945 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 946 ivs.getPackageName()); 947 verificationIntent.setComponent(mIntentFilterVerifierComponent); 948 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 949 950 UserHandle user = new UserHandle(userId); 951 mContext.sendBroadcastAsUser(verificationIntent, user); 952 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 953 "Sending IntentFilter verification broadcast"); 954 } 955 956 public void receiveVerificationResponse(int verificationId) { 957 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 958 959 final boolean verified = ivs.isVerified(); 960 961 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 962 final int count = filters.size(); 963 if (DEBUG_DOMAIN_VERIFICATION) { 964 Slog.i(TAG, "Received verification response " + verificationId 965 + " for " + count + " filters, verified=" + verified); 966 } 967 for (int n=0; n<count; n++) { 968 PackageParser.ActivityIntentInfo filter = filters.get(n); 969 filter.setVerified(verified); 970 971 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 972 + " verified with result:" + verified + " and hosts:" 973 + ivs.getHostsString()); 974 } 975 976 mIntentFilterVerificationStates.remove(verificationId); 977 978 final String packageName = ivs.getPackageName(); 979 IntentFilterVerificationInfo ivi = null; 980 981 synchronized (mPackages) { 982 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 983 } 984 if (ivi == null) { 985 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 986 + verificationId + " packageName:" + packageName); 987 return; 988 } 989 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 990 "Updating IntentFilterVerificationInfo for package " + packageName 991 +" verificationId:" + verificationId); 992 993 synchronized (mPackages) { 994 if (verified) { 995 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 996 } else { 997 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 998 } 999 scheduleWriteSettingsLocked(); 1000 1001 final int userId = ivs.getUserId(); 1002 if (userId != UserHandle.USER_ALL) { 1003 final int userStatus = 1004 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 1005 1006 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 1007 boolean needUpdate = false; 1008 1009 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 1010 // already been set by the User thru the Disambiguation dialog 1011 switch (userStatus) { 1012 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 1013 if (verified) { 1014 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 1015 } else { 1016 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 1017 } 1018 needUpdate = true; 1019 break; 1020 1021 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 1022 if (verified) { 1023 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 1024 needUpdate = true; 1025 } 1026 break; 1027 1028 default: 1029 // Nothing to do 1030 } 1031 1032 if (needUpdate) { 1033 mSettings.updateIntentFilterVerificationStatusLPw( 1034 packageName, updatedStatus, userId); 1035 scheduleWritePackageRestrictionsLocked(userId); 1036 } 1037 } 1038 } 1039 } 1040 1041 @Override 1042 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 1043 ActivityIntentInfo filter, String packageName) { 1044 if (!hasValidDomains(filter)) { 1045 return false; 1046 } 1047 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 1048 if (ivs == null) { 1049 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 1050 packageName); 1051 } 1052 if (DEBUG_DOMAIN_VERIFICATION) { 1053 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 1054 } 1055 ivs.addFilter(filter); 1056 return true; 1057 } 1058 1059 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 1060 int userId, int verificationId, String packageName) { 1061 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 1062 verifierUid, userId, packageName); 1063 ivs.setPendingState(); 1064 synchronized (mPackages) { 1065 mIntentFilterVerificationStates.append(verificationId, ivs); 1066 mCurrentIntentFilterVerifications.add(verificationId); 1067 } 1068 return ivs; 1069 } 1070 } 1071 1072 private static boolean hasValidDomains(ActivityIntentInfo filter) { 1073 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 1074 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 1075 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 1076 } 1077 1078 // Set of pending broadcasts for aggregating enable/disable of components. 1079 static class PendingPackageBroadcasts { 1080 // for each user id, a map of <package name -> components within that package> 1081 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 1082 1083 public PendingPackageBroadcasts() { 1084 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 1085 } 1086 1087 public ArrayList<String> get(int userId, String packageName) { 1088 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1089 return packages.get(packageName); 1090 } 1091 1092 public void put(int userId, String packageName, ArrayList<String> components) { 1093 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1094 packages.put(packageName, components); 1095 } 1096 1097 public void remove(int userId, String packageName) { 1098 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 1099 if (packages != null) { 1100 packages.remove(packageName); 1101 } 1102 } 1103 1104 public void remove(int userId) { 1105 mUidMap.remove(userId); 1106 } 1107 1108 public int userIdCount() { 1109 return mUidMap.size(); 1110 } 1111 1112 public int userIdAt(int n) { 1113 return mUidMap.keyAt(n); 1114 } 1115 1116 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 1117 return mUidMap.get(userId); 1118 } 1119 1120 public int size() { 1121 // total number of pending broadcast entries across all userIds 1122 int num = 0; 1123 for (int i = 0; i< mUidMap.size(); i++) { 1124 num += mUidMap.valueAt(i).size(); 1125 } 1126 return num; 1127 } 1128 1129 public void clear() { 1130 mUidMap.clear(); 1131 } 1132 1133 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1134 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1135 if (map == null) { 1136 map = new ArrayMap<String, ArrayList<String>>(); 1137 mUidMap.put(userId, map); 1138 } 1139 return map; 1140 } 1141 } 1142 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1143 1144 // Service Connection to remote media container service to copy 1145 // package uri's from external media onto secure containers 1146 // or internal storage. 1147 private IMediaContainerService mContainerService = null; 1148 1149 static final int SEND_PENDING_BROADCAST = 1; 1150 static final int MCS_BOUND = 3; 1151 static final int END_COPY = 4; 1152 static final int INIT_COPY = 5; 1153 static final int MCS_UNBIND = 6; 1154 static final int START_CLEANING_PACKAGE = 7; 1155 static final int FIND_INSTALL_LOC = 8; 1156 static final int POST_INSTALL = 9; 1157 static final int MCS_RECONNECT = 10; 1158 static final int MCS_GIVE_UP = 11; 1159 static final int UPDATED_MEDIA_STATUS = 12; 1160 static final int WRITE_SETTINGS = 13; 1161 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1162 static final int PACKAGE_VERIFIED = 15; 1163 static final int CHECK_PENDING_VERIFICATION = 16; 1164 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1165 static final int INTENT_FILTER_VERIFIED = 18; 1166 static final int WRITE_PACKAGE_LIST = 19; 1167 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20; 1168 1169 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1170 1171 // Delay time in millisecs 1172 static final int BROADCAST_DELAY = 10 * 1000; 1173 1174 static UserManagerService sUserManager; 1175 1176 // Stores a list of users whose package restrictions file needs to be updated 1177 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1178 1179 final private DefaultContainerConnection mDefContainerConn = 1180 new DefaultContainerConnection(); 1181 class DefaultContainerConnection implements ServiceConnection { 1182 public void onServiceConnected(ComponentName name, IBinder service) { 1183 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1184 final IMediaContainerService imcs = IMediaContainerService.Stub 1185 .asInterface(Binder.allowBlocking(service)); 1186 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1187 } 1188 1189 public void onServiceDisconnected(ComponentName name) { 1190 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1191 } 1192 } 1193 1194 // Recordkeeping of restore-after-install operations that are currently in flight 1195 // between the Package Manager and the Backup Manager 1196 static class PostInstallData { 1197 public InstallArgs args; 1198 public PackageInstalledInfo res; 1199 1200 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1201 args = _a; 1202 res = _r; 1203 } 1204 } 1205 1206 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1207 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1208 1209 // XML tags for backup/restore of various bits of state 1210 private static final String TAG_PREFERRED_BACKUP = "pa"; 1211 private static final String TAG_DEFAULT_APPS = "da"; 1212 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1213 1214 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1215 private static final String TAG_ALL_GRANTS = "rt-grants"; 1216 private static final String TAG_GRANT = "grant"; 1217 private static final String ATTR_PACKAGE_NAME = "pkg"; 1218 1219 private static final String TAG_PERMISSION = "perm"; 1220 private static final String ATTR_PERMISSION_NAME = "name"; 1221 private static final String ATTR_IS_GRANTED = "g"; 1222 private static final String ATTR_USER_SET = "set"; 1223 private static final String ATTR_USER_FIXED = "fixed"; 1224 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1225 1226 // System/policy permission grants are not backed up 1227 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1228 FLAG_PERMISSION_POLICY_FIXED 1229 | FLAG_PERMISSION_SYSTEM_FIXED 1230 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1231 1232 // And we back up these user-adjusted states 1233 private static final int USER_RUNTIME_GRANT_MASK = 1234 FLAG_PERMISSION_USER_SET 1235 | FLAG_PERMISSION_USER_FIXED 1236 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1237 1238 final @Nullable String mRequiredVerifierPackage; 1239 final @NonNull String mRequiredInstallerPackage; 1240 final @NonNull String mRequiredUninstallerPackage; 1241 final @Nullable String mSetupWizardPackage; 1242 final @Nullable String mStorageManagerPackage; 1243 final @NonNull String mServicesSystemSharedLibraryPackageName; 1244 final @NonNull String mSharedSystemSharedLibraryPackageName; 1245 1246 final boolean mPermissionReviewRequired; 1247 1248 private final PackageUsage mPackageUsage = new PackageUsage(); 1249 private final CompilerStats mCompilerStats = new CompilerStats(); 1250 1251 class PackageHandler extends Handler { 1252 private boolean mBound = false; 1253 final ArrayList<HandlerParams> mPendingInstalls = 1254 new ArrayList<HandlerParams>(); 1255 1256 private boolean connectToService() { 1257 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1258 " DefaultContainerService"); 1259 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1260 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1261 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1262 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1263 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1264 mBound = true; 1265 return true; 1266 } 1267 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1268 return false; 1269 } 1270 1271 private void disconnectService() { 1272 mContainerService = null; 1273 mBound = false; 1274 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1275 mContext.unbindService(mDefContainerConn); 1276 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1277 } 1278 1279 PackageHandler(Looper looper) { 1280 super(looper); 1281 } 1282 1283 public void handleMessage(Message msg) { 1284 try { 1285 doHandleMessage(msg); 1286 } finally { 1287 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1288 } 1289 } 1290 1291 void doHandleMessage(Message msg) { 1292 switch (msg.what) { 1293 case INIT_COPY: { 1294 HandlerParams params = (HandlerParams) msg.obj; 1295 int idx = mPendingInstalls.size(); 1296 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1297 // If a bind was already initiated we dont really 1298 // need to do anything. The pending install 1299 // will be processed later on. 1300 if (!mBound) { 1301 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1302 System.identityHashCode(mHandler)); 1303 // If this is the only one pending we might 1304 // have to bind to the service again. 1305 if (!connectToService()) { 1306 Slog.e(TAG, "Failed to bind to media container service"); 1307 params.serviceError(); 1308 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1309 System.identityHashCode(mHandler)); 1310 if (params.traceMethod != null) { 1311 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1312 params.traceCookie); 1313 } 1314 return; 1315 } else { 1316 // Once we bind to the service, the first 1317 // pending request will be processed. 1318 mPendingInstalls.add(idx, params); 1319 } 1320 } else { 1321 mPendingInstalls.add(idx, params); 1322 // Already bound to the service. Just make 1323 // sure we trigger off processing the first request. 1324 if (idx == 0) { 1325 mHandler.sendEmptyMessage(MCS_BOUND); 1326 } 1327 } 1328 break; 1329 } 1330 case MCS_BOUND: { 1331 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1332 if (msg.obj != null) { 1333 mContainerService = (IMediaContainerService) msg.obj; 1334 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1335 System.identityHashCode(mHandler)); 1336 } 1337 if (mContainerService == null) { 1338 if (!mBound) { 1339 // Something seriously wrong since we are not bound and we are not 1340 // waiting for connection. Bail out. 1341 Slog.e(TAG, "Cannot bind to media container service"); 1342 for (HandlerParams params : mPendingInstalls) { 1343 // Indicate service bind error 1344 params.serviceError(); 1345 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1346 System.identityHashCode(params)); 1347 if (params.traceMethod != null) { 1348 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1349 params.traceMethod, params.traceCookie); 1350 } 1351 return; 1352 } 1353 mPendingInstalls.clear(); 1354 } else { 1355 Slog.w(TAG, "Waiting to connect to media container service"); 1356 } 1357 } else if (mPendingInstalls.size() > 0) { 1358 HandlerParams params = mPendingInstalls.get(0); 1359 if (params != null) { 1360 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1361 System.identityHashCode(params)); 1362 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1363 if (params.startCopy()) { 1364 // We are done... look for more work or to 1365 // go idle. 1366 if (DEBUG_SD_INSTALL) Log.i(TAG, 1367 "Checking for more work or unbind..."); 1368 // Delete pending install 1369 if (mPendingInstalls.size() > 0) { 1370 mPendingInstalls.remove(0); 1371 } 1372 if (mPendingInstalls.size() == 0) { 1373 if (mBound) { 1374 if (DEBUG_SD_INSTALL) Log.i(TAG, 1375 "Posting delayed MCS_UNBIND"); 1376 removeMessages(MCS_UNBIND); 1377 Message ubmsg = obtainMessage(MCS_UNBIND); 1378 // Unbind after a little delay, to avoid 1379 // continual thrashing. 1380 sendMessageDelayed(ubmsg, 10000); 1381 } 1382 } else { 1383 // There are more pending requests in queue. 1384 // Just post MCS_BOUND message to trigger processing 1385 // of next pending install. 1386 if (DEBUG_SD_INSTALL) Log.i(TAG, 1387 "Posting MCS_BOUND for next work"); 1388 mHandler.sendEmptyMessage(MCS_BOUND); 1389 } 1390 } 1391 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1392 } 1393 } else { 1394 // Should never happen ideally. 1395 Slog.w(TAG, "Empty queue"); 1396 } 1397 break; 1398 } 1399 case MCS_RECONNECT: { 1400 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1401 if (mPendingInstalls.size() > 0) { 1402 if (mBound) { 1403 disconnectService(); 1404 } 1405 if (!connectToService()) { 1406 Slog.e(TAG, "Failed to bind to media container service"); 1407 for (HandlerParams params : mPendingInstalls) { 1408 // Indicate service bind error 1409 params.serviceError(); 1410 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1411 System.identityHashCode(params)); 1412 } 1413 mPendingInstalls.clear(); 1414 } 1415 } 1416 break; 1417 } 1418 case MCS_UNBIND: { 1419 // If there is no actual work left, then time to unbind. 1420 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1421 1422 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1423 if (mBound) { 1424 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1425 1426 disconnectService(); 1427 } 1428 } else if (mPendingInstalls.size() > 0) { 1429 // There are more pending requests in queue. 1430 // Just post MCS_BOUND message to trigger processing 1431 // of next pending install. 1432 mHandler.sendEmptyMessage(MCS_BOUND); 1433 } 1434 1435 break; 1436 } 1437 case MCS_GIVE_UP: { 1438 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1439 HandlerParams params = mPendingInstalls.remove(0); 1440 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1441 System.identityHashCode(params)); 1442 break; 1443 } 1444 case SEND_PENDING_BROADCAST: { 1445 String packages[]; 1446 ArrayList<String> components[]; 1447 int size = 0; 1448 int uids[]; 1449 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1450 synchronized (mPackages) { 1451 if (mPendingBroadcasts == null) { 1452 return; 1453 } 1454 size = mPendingBroadcasts.size(); 1455 if (size <= 0) { 1456 // Nothing to be done. Just return 1457 return; 1458 } 1459 packages = new String[size]; 1460 components = new ArrayList[size]; 1461 uids = new int[size]; 1462 int i = 0; // filling out the above arrays 1463 1464 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1465 int packageUserId = mPendingBroadcasts.userIdAt(n); 1466 Iterator<Map.Entry<String, ArrayList<String>>> it 1467 = mPendingBroadcasts.packagesForUserId(packageUserId) 1468 .entrySet().iterator(); 1469 while (it.hasNext() && i < size) { 1470 Map.Entry<String, ArrayList<String>> ent = it.next(); 1471 packages[i] = ent.getKey(); 1472 components[i] = ent.getValue(); 1473 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1474 uids[i] = (ps != null) 1475 ? UserHandle.getUid(packageUserId, ps.appId) 1476 : -1; 1477 i++; 1478 } 1479 } 1480 size = i; 1481 mPendingBroadcasts.clear(); 1482 } 1483 // Send broadcasts 1484 for (int i = 0; i < size; i++) { 1485 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1486 } 1487 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1488 break; 1489 } 1490 case START_CLEANING_PACKAGE: { 1491 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1492 final String packageName = (String)msg.obj; 1493 final int userId = msg.arg1; 1494 final boolean andCode = msg.arg2 != 0; 1495 synchronized (mPackages) { 1496 if (userId == UserHandle.USER_ALL) { 1497 int[] users = sUserManager.getUserIds(); 1498 for (int user : users) { 1499 mSettings.addPackageToCleanLPw( 1500 new PackageCleanItem(user, packageName, andCode)); 1501 } 1502 } else { 1503 mSettings.addPackageToCleanLPw( 1504 new PackageCleanItem(userId, packageName, andCode)); 1505 } 1506 } 1507 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1508 startCleaningPackages(); 1509 } break; 1510 case POST_INSTALL: { 1511 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1512 1513 PostInstallData data = mRunningInstalls.get(msg.arg1); 1514 final boolean didRestore = (msg.arg2 != 0); 1515 mRunningInstalls.delete(msg.arg1); 1516 1517 if (data != null) { 1518 InstallArgs args = data.args; 1519 PackageInstalledInfo parentRes = data.res; 1520 1521 final boolean grantPermissions = (args.installFlags 1522 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1523 final boolean killApp = (args.installFlags 1524 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1525 final String[] grantedPermissions = args.installGrantPermissions; 1526 1527 // Handle the parent package 1528 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1529 grantedPermissions, didRestore, args.installerPackageName, 1530 args.observer); 1531 1532 // Handle the child packages 1533 final int childCount = (parentRes.addedChildPackages != null) 1534 ? parentRes.addedChildPackages.size() : 0; 1535 for (int i = 0; i < childCount; i++) { 1536 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1537 handlePackagePostInstall(childRes, grantPermissions, killApp, 1538 grantedPermissions, false, args.installerPackageName, 1539 args.observer); 1540 } 1541 1542 // Log tracing if needed 1543 if (args.traceMethod != null) { 1544 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1545 args.traceCookie); 1546 } 1547 } else { 1548 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1549 } 1550 1551 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1552 } break; 1553 case UPDATED_MEDIA_STATUS: { 1554 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1555 boolean reportStatus = msg.arg1 == 1; 1556 boolean doGc = msg.arg2 == 1; 1557 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1558 if (doGc) { 1559 // Force a gc to clear up stale containers. 1560 Runtime.getRuntime().gc(); 1561 } 1562 if (msg.obj != null) { 1563 @SuppressWarnings("unchecked") 1564 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1565 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1566 // Unload containers 1567 unloadAllContainers(args); 1568 } 1569 if (reportStatus) { 1570 try { 1571 if (DEBUG_SD_INSTALL) Log.i(TAG, 1572 "Invoking StorageManagerService call back"); 1573 PackageHelper.getStorageManager().finishMediaUpdate(); 1574 } catch (RemoteException e) { 1575 Log.e(TAG, "StorageManagerService not running?"); 1576 } 1577 } 1578 } break; 1579 case WRITE_SETTINGS: { 1580 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1581 synchronized (mPackages) { 1582 removeMessages(WRITE_SETTINGS); 1583 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1584 mSettings.writeLPr(); 1585 mDirtyUsers.clear(); 1586 } 1587 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1588 } break; 1589 case WRITE_PACKAGE_RESTRICTIONS: { 1590 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1591 synchronized (mPackages) { 1592 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1593 for (int userId : mDirtyUsers) { 1594 mSettings.writePackageRestrictionsLPr(userId); 1595 } 1596 mDirtyUsers.clear(); 1597 } 1598 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1599 } break; 1600 case WRITE_PACKAGE_LIST: { 1601 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1602 synchronized (mPackages) { 1603 removeMessages(WRITE_PACKAGE_LIST); 1604 mSettings.writePackageListLPr(msg.arg1); 1605 } 1606 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1607 } break; 1608 case CHECK_PENDING_VERIFICATION: { 1609 final int verificationId = msg.arg1; 1610 final PackageVerificationState state = mPendingVerification.get(verificationId); 1611 1612 if ((state != null) && !state.timeoutExtended()) { 1613 final InstallArgs args = state.getInstallArgs(); 1614 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1615 1616 Slog.i(TAG, "Verification timed out for " + originUri); 1617 mPendingVerification.remove(verificationId); 1618 1619 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1620 1621 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1622 Slog.i(TAG, "Continuing with installation of " + originUri); 1623 state.setVerifierResponse(Binder.getCallingUid(), 1624 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1625 broadcastPackageVerified(verificationId, originUri, 1626 PackageManager.VERIFICATION_ALLOW, 1627 state.getInstallArgs().getUser()); 1628 try { 1629 ret = args.copyApk(mContainerService, true); 1630 } catch (RemoteException e) { 1631 Slog.e(TAG, "Could not contact the ContainerService"); 1632 } 1633 } else { 1634 broadcastPackageVerified(verificationId, originUri, 1635 PackageManager.VERIFICATION_REJECT, 1636 state.getInstallArgs().getUser()); 1637 } 1638 1639 Trace.asyncTraceEnd( 1640 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1641 1642 processPendingInstall(args, ret); 1643 mHandler.sendEmptyMessage(MCS_UNBIND); 1644 } 1645 break; 1646 } 1647 case PACKAGE_VERIFIED: { 1648 final int verificationId = msg.arg1; 1649 1650 final PackageVerificationState state = mPendingVerification.get(verificationId); 1651 if (state == null) { 1652 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1653 break; 1654 } 1655 1656 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1657 1658 state.setVerifierResponse(response.callerUid, response.code); 1659 1660 if (state.isVerificationComplete()) { 1661 mPendingVerification.remove(verificationId); 1662 1663 final InstallArgs args = state.getInstallArgs(); 1664 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1665 1666 int ret; 1667 if (state.isInstallAllowed()) { 1668 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1669 broadcastPackageVerified(verificationId, originUri, 1670 response.code, state.getInstallArgs().getUser()); 1671 try { 1672 ret = args.copyApk(mContainerService, true); 1673 } catch (RemoteException e) { 1674 Slog.e(TAG, "Could not contact the ContainerService"); 1675 } 1676 } else { 1677 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1678 } 1679 1680 Trace.asyncTraceEnd( 1681 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1682 1683 processPendingInstall(args, ret); 1684 mHandler.sendEmptyMessage(MCS_UNBIND); 1685 } 1686 1687 break; 1688 } 1689 case START_INTENT_FILTER_VERIFICATIONS: { 1690 IFVerificationParams params = (IFVerificationParams) msg.obj; 1691 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1692 params.replacing, params.pkg); 1693 break; 1694 } 1695 case INTENT_FILTER_VERIFIED: { 1696 final int verificationId = msg.arg1; 1697 1698 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1699 verificationId); 1700 if (state == null) { 1701 Slog.w(TAG, "Invalid IntentFilter verification token " 1702 + verificationId + " received"); 1703 break; 1704 } 1705 1706 final int userId = state.getUserId(); 1707 1708 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1709 "Processing IntentFilter verification with token:" 1710 + verificationId + " and userId:" + userId); 1711 1712 final IntentFilterVerificationResponse response = 1713 (IntentFilterVerificationResponse) msg.obj; 1714 1715 state.setVerifierResponse(response.callerUid, response.code); 1716 1717 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1718 "IntentFilter verification with token:" + verificationId 1719 + " and userId:" + userId 1720 + " is settings verifier response with response code:" 1721 + response.code); 1722 1723 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1724 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1725 + response.getFailedDomainsString()); 1726 } 1727 1728 if (state.isVerificationComplete()) { 1729 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1730 } else { 1731 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1732 "IntentFilter verification with token:" + verificationId 1733 + " was not said to be complete"); 1734 } 1735 1736 break; 1737 } 1738 case INSTANT_APP_RESOLUTION_PHASE_TWO: { 1739 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext, 1740 mInstantAppResolverConnection, 1741 (InstantAppRequest) msg.obj, 1742 mInstantAppInstallerActivity, 1743 mHandler); 1744 } 1745 } 1746 } 1747 } 1748 1749 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1750 boolean killApp, String[] grantedPermissions, 1751 boolean launchedForRestore, String installerPackage, 1752 IPackageInstallObserver2 installObserver) { 1753 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1754 // Send the removed broadcasts 1755 if (res.removedInfo != null) { 1756 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1757 } 1758 1759 // Now that we successfully installed the package, grant runtime 1760 // permissions if requested before broadcasting the install. Also 1761 // for legacy apps in permission review mode we clear the permission 1762 // review flag which is used to emulate runtime permissions for 1763 // legacy apps. 1764 if (grantPermissions) { 1765 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1766 } 1767 1768 final boolean update = res.removedInfo != null 1769 && res.removedInfo.removedPackage != null; 1770 1771 // If this is the first time we have child packages for a disabled privileged 1772 // app that had no children, we grant requested runtime permissions to the new 1773 // children if the parent on the system image had them already granted. 1774 if (res.pkg.parentPackage != null) { 1775 synchronized (mPackages) { 1776 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1777 } 1778 } 1779 1780 synchronized (mPackages) { 1781 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers); 1782 } 1783 1784 final String packageName = res.pkg.applicationInfo.packageName; 1785 1786 // Determine the set of users who are adding this package for 1787 // the first time vs. those who are seeing an update. 1788 int[] firstUsers = EMPTY_INT_ARRAY; 1789 int[] updateUsers = EMPTY_INT_ARRAY; 1790 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0; 1791 final PackageSetting ps = (PackageSetting) res.pkg.mExtras; 1792 for (int newUser : res.newUsers) { 1793 if (ps.getInstantApp(newUser)) { 1794 continue; 1795 } 1796 if (allNewUsers) { 1797 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1798 continue; 1799 } 1800 boolean isNew = true; 1801 for (int origUser : res.origUsers) { 1802 if (origUser == newUser) { 1803 isNew = false; 1804 break; 1805 } 1806 } 1807 if (isNew) { 1808 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1809 } else { 1810 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1811 } 1812 } 1813 1814 // Send installed broadcasts if the package is not a static shared lib. 1815 if (res.pkg.staticSharedLibName == null) { 1816 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1817 1818 // Send added for users that see the package for the first time 1819 // sendPackageAddedForNewUsers also deals with system apps 1820 int appId = UserHandle.getAppId(res.uid); 1821 boolean isSystem = res.pkg.applicationInfo.isSystemApp(); 1822 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers); 1823 1824 // Send added for users that don't see the package for the first time 1825 Bundle extras = new Bundle(1); 1826 extras.putInt(Intent.EXTRA_UID, res.uid); 1827 if (update) { 1828 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1829 } 1830 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1831 extras, 0 /*flags*/, null /*targetPackage*/, 1832 null /*finishedReceiver*/, updateUsers); 1833 1834 // Send replaced for users that don't see the package for the first time 1835 if (update) { 1836 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1837 packageName, extras, 0 /*flags*/, 1838 null /*targetPackage*/, null /*finishedReceiver*/, 1839 updateUsers); 1840 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1841 null /*package*/, null /*extras*/, 0 /*flags*/, 1842 packageName /*targetPackage*/, 1843 null /*finishedReceiver*/, updateUsers); 1844 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1845 // First-install and we did a restore, so we're responsible for the 1846 // first-launch broadcast. 1847 if (DEBUG_BACKUP) { 1848 Slog.i(TAG, "Post-restore of " + packageName 1849 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1850 } 1851 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1852 } 1853 1854 // Send broadcast package appeared if forward locked/external for all users 1855 // treat asec-hosted packages like removable media on upgrade 1856 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1857 if (DEBUG_INSTALL) { 1858 Slog.i(TAG, "upgrading pkg " + res.pkg 1859 + " is ASEC-hosted -> AVAILABLE"); 1860 } 1861 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1862 ArrayList<String> pkgList = new ArrayList<>(1); 1863 pkgList.add(packageName); 1864 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1865 } 1866 } 1867 1868 // Work that needs to happen on first install within each user 1869 if (firstUsers != null && firstUsers.length > 0) { 1870 synchronized (mPackages) { 1871 for (int userId : firstUsers) { 1872 // If this app is a browser and it's newly-installed for some 1873 // users, clear any default-browser state in those users. The 1874 // app's nature doesn't depend on the user, so we can just check 1875 // its browser nature in any user and generalize. 1876 if (packageIsBrowser(packageName, userId)) { 1877 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1878 } 1879 1880 // We may also need to apply pending (restored) runtime 1881 // permission grants within these users. 1882 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1883 } 1884 } 1885 } 1886 1887 // Log current value of "unknown sources" setting 1888 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1889 getUnknownSourcesSettings()); 1890 1891 // Force a gc to clear up things 1892 Runtime.getRuntime().gc(); 1893 1894 // Remove the replaced package's older resources safely now 1895 // We delete after a gc for applications on sdcard. 1896 if (res.removedInfo != null && res.removedInfo.args != null) { 1897 synchronized (mInstallLock) { 1898 res.removedInfo.args.doPostDeleteLI(true); 1899 } 1900 } 1901 1902 // Notify DexManager that the package was installed for new users. 1903 // The updated users should already be indexed and the package code paths 1904 // should not change. 1905 // Don't notify the manager for ephemeral apps as they are not expected to 1906 // survive long enough to benefit of background optimizations. 1907 for (int userId : firstUsers) { 1908 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId); 1909 mDexManager.notifyPackageInstalled(info, userId); 1910 } 1911 } 1912 1913 // If someone is watching installs - notify them 1914 if (installObserver != null) { 1915 try { 1916 Bundle extras = extrasForInstallResult(res); 1917 installObserver.onPackageInstalled(res.name, res.returnCode, 1918 res.returnMsg, extras); 1919 } catch (RemoteException e) { 1920 Slog.i(TAG, "Observer no longer exists."); 1921 } 1922 } 1923 } 1924 1925 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1926 PackageParser.Package pkg) { 1927 if (pkg.parentPackage == null) { 1928 return; 1929 } 1930 if (pkg.requestedPermissions == null) { 1931 return; 1932 } 1933 final PackageSetting disabledSysParentPs = mSettings 1934 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1935 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1936 || !disabledSysParentPs.isPrivileged() 1937 || (disabledSysParentPs.childPackageNames != null 1938 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1939 return; 1940 } 1941 final int[] allUserIds = sUserManager.getUserIds(); 1942 final int permCount = pkg.requestedPermissions.size(); 1943 for (int i = 0; i < permCount; i++) { 1944 String permission = pkg.requestedPermissions.get(i); 1945 BasePermission bp = mSettings.mPermissions.get(permission); 1946 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1947 continue; 1948 } 1949 for (int userId : allUserIds) { 1950 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1951 permission, userId)) { 1952 grantRuntimePermission(pkg.packageName, permission, userId); 1953 } 1954 } 1955 } 1956 } 1957 1958 private StorageEventListener mStorageListener = new StorageEventListener() { 1959 @Override 1960 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1961 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1962 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1963 final String volumeUuid = vol.getFsUuid(); 1964 1965 // Clean up any users or apps that were removed or recreated 1966 // while this volume was missing 1967 sUserManager.reconcileUsers(volumeUuid); 1968 reconcileApps(volumeUuid); 1969 1970 // Clean up any install sessions that expired or were 1971 // cancelled while this volume was missing 1972 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1973 1974 loadPrivatePackages(vol); 1975 1976 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1977 unloadPrivatePackages(vol); 1978 } 1979 } 1980 1981 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1982 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1983 updateExternalMediaStatus(true, false); 1984 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1985 updateExternalMediaStatus(false, false); 1986 } 1987 } 1988 } 1989 1990 @Override 1991 public void onVolumeForgotten(String fsUuid) { 1992 if (TextUtils.isEmpty(fsUuid)) { 1993 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1994 return; 1995 } 1996 1997 // Remove any apps installed on the forgotten volume 1998 synchronized (mPackages) { 1999 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 2000 for (PackageSetting ps : packages) { 2001 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 2002 deletePackageVersioned(new VersionedPackage(ps.name, 2003 PackageManager.VERSION_CODE_HIGHEST), 2004 new LegacyPackageDeleteObserver(null).getBinder(), 2005 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 2006 // Try very hard to release any references to this package 2007 // so we don't risk the system server being killed due to 2008 // open FDs 2009 AttributeCache.instance().removePackage(ps.name); 2010 } 2011 2012 mSettings.onVolumeForgotten(fsUuid); 2013 mSettings.writeLPr(); 2014 } 2015 } 2016 }; 2017 2018 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 2019 String[] grantedPermissions) { 2020 for (int userId : userIds) { 2021 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 2022 } 2023 } 2024 2025 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 2026 String[] grantedPermissions) { 2027 SettingBase sb = (SettingBase) pkg.mExtras; 2028 if (sb == null) { 2029 return; 2030 } 2031 2032 PermissionsState permissionsState = sb.getPermissionsState(); 2033 2034 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 2035 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 2036 2037 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 2038 >= Build.VERSION_CODES.M; 2039 2040 for (String permission : pkg.requestedPermissions) { 2041 final BasePermission bp; 2042 synchronized (mPackages) { 2043 bp = mSettings.mPermissions.get(permission); 2044 } 2045 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 2046 && (grantedPermissions == null 2047 || ArrayUtils.contains(grantedPermissions, permission))) { 2048 final int flags = permissionsState.getPermissionFlags(permission, userId); 2049 if (supportsRuntimePermissions) { 2050 // Installer cannot change immutable permissions. 2051 if ((flags & immutableFlags) == 0) { 2052 grantRuntimePermission(pkg.packageName, permission, userId); 2053 } 2054 } else if (mPermissionReviewRequired) { 2055 // In permission review mode we clear the review flag when we 2056 // are asked to install the app with all permissions granted. 2057 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 2058 updatePermissionFlags(permission, pkg.packageName, 2059 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId); 2060 } 2061 } 2062 } 2063 } 2064 } 2065 2066 Bundle extrasForInstallResult(PackageInstalledInfo res) { 2067 Bundle extras = null; 2068 switch (res.returnCode) { 2069 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 2070 extras = new Bundle(); 2071 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 2072 res.origPermission); 2073 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 2074 res.origPackage); 2075 break; 2076 } 2077 case PackageManager.INSTALL_SUCCEEDED: { 2078 extras = new Bundle(); 2079 extras.putBoolean(Intent.EXTRA_REPLACING, 2080 res.removedInfo != null && res.removedInfo.removedPackage != null); 2081 break; 2082 } 2083 } 2084 return extras; 2085 } 2086 2087 void scheduleWriteSettingsLocked() { 2088 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 2089 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 2090 } 2091 } 2092 2093 void scheduleWritePackageListLocked(int userId) { 2094 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 2095 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 2096 msg.arg1 = userId; 2097 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 2098 } 2099 } 2100 2101 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 2102 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 2103 scheduleWritePackageRestrictionsLocked(userId); 2104 } 2105 2106 void scheduleWritePackageRestrictionsLocked(int userId) { 2107 final int[] userIds = (userId == UserHandle.USER_ALL) 2108 ? sUserManager.getUserIds() : new int[]{userId}; 2109 for (int nextUserId : userIds) { 2110 if (!sUserManager.exists(nextUserId)) return; 2111 mDirtyUsers.add(nextUserId); 2112 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 2113 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 2114 } 2115 } 2116 } 2117 2118 public static PackageManagerService main(Context context, Installer installer, 2119 boolean factoryTest, boolean onlyCore) { 2120 // Self-check for initial settings. 2121 PackageManagerServiceCompilerMapping.checkProperties(); 2122 2123 PackageManagerService m = new PackageManagerService(context, installer, 2124 factoryTest, onlyCore); 2125 m.enableSystemUserPackages(); 2126 ServiceManager.addService("package", m); 2127 return m; 2128 } 2129 2130 private void enableSystemUserPackages() { 2131 if (!UserManager.isSplitSystemUser()) { 2132 return; 2133 } 2134 // For system user, enable apps based on the following conditions: 2135 // - app is whitelisted or belong to one of these groups: 2136 // -- system app which has no launcher icons 2137 // -- system app which has INTERACT_ACROSS_USERS permission 2138 // -- system IME app 2139 // - app is not in the blacklist 2140 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 2141 Set<String> enableApps = new ArraySet<>(); 2142 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 2143 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 2144 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 2145 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2146 enableApps.addAll(wlApps); 2147 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2148 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2149 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2150 enableApps.removeAll(blApps); 2151 Log.i(TAG, "Applications installed for system user: " + enableApps); 2152 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2153 UserHandle.SYSTEM); 2154 final int allAppsSize = allAps.size(); 2155 synchronized (mPackages) { 2156 for (int i = 0; i < allAppsSize; i++) { 2157 String pName = allAps.get(i); 2158 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2159 // Should not happen, but we shouldn't be failing if it does 2160 if (pkgSetting == null) { 2161 continue; 2162 } 2163 boolean install = enableApps.contains(pName); 2164 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2165 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2166 + " for system user"); 2167 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2168 } 2169 } 2170 scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM); 2171 } 2172 } 2173 2174 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2175 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2176 Context.DISPLAY_SERVICE); 2177 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2178 } 2179 2180 /** 2181 * Requests that files preopted on a secondary system partition be copied to the data partition 2182 * if possible. Note that the actual copying of the files is accomplished by init for security 2183 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2184 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2185 */ 2186 private static void requestCopyPreoptedFiles() { 2187 final int WAIT_TIME_MS = 100; 2188 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2189 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2190 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2191 // We will wait for up to 100 seconds. 2192 final long timeStart = SystemClock.uptimeMillis(); 2193 final long timeEnd = timeStart + 100 * 1000; 2194 long timeNow = timeStart; 2195 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2196 try { 2197 Thread.sleep(WAIT_TIME_MS); 2198 } catch (InterruptedException e) { 2199 // Do nothing 2200 } 2201 timeNow = SystemClock.uptimeMillis(); 2202 if (timeNow > timeEnd) { 2203 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2204 Slog.wtf(TAG, "cppreopt did not finish!"); 2205 break; 2206 } 2207 } 2208 2209 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms"); 2210 } 2211 } 2212 2213 public PackageManagerService(Context context, Installer installer, 2214 boolean factoryTest, boolean onlyCore) { 2215 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager"); 2216 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2217 SystemClock.uptimeMillis()); 2218 2219 if (mSdkVersion <= 0) { 2220 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2221 } 2222 2223 mContext = context; 2224 2225 mPermissionReviewRequired = context.getResources().getBoolean( 2226 R.bool.config_permissionReviewRequired); 2227 2228 mFactoryTest = factoryTest; 2229 mOnlyCore = onlyCore; 2230 mMetrics = new DisplayMetrics(); 2231 mSettings = new Settings(mPackages); 2232 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2233 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2234 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2235 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2236 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2237 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2238 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2239 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2240 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2241 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2242 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2243 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2244 2245 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2246 if (separateProcesses != null && separateProcesses.length() > 0) { 2247 if ("*".equals(separateProcesses)) { 2248 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2249 mSeparateProcesses = null; 2250 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2251 } else { 2252 mDefParseFlags = 0; 2253 mSeparateProcesses = separateProcesses.split(","); 2254 Slog.w(TAG, "Running with debug.separate_processes: " 2255 + separateProcesses); 2256 } 2257 } else { 2258 mDefParseFlags = 0; 2259 mSeparateProcesses = null; 2260 } 2261 2262 mInstaller = installer; 2263 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2264 "*dexopt*"); 2265 mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock); 2266 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2267 2268 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2269 FgThread.get().getLooper()); 2270 2271 getDefaultDisplayMetrics(context, mMetrics); 2272 2273 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config"); 2274 SystemConfig systemConfig = SystemConfig.getInstance(); 2275 mGlobalGids = systemConfig.getGlobalGids(); 2276 mSystemPermissions = systemConfig.getSystemPermissions(); 2277 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2278 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2279 2280 mProtectedPackages = new ProtectedPackages(mContext); 2281 2282 synchronized (mInstallLock) { 2283 // writer 2284 synchronized (mPackages) { 2285 mHandlerThread = new ServiceThread(TAG, 2286 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2287 mHandlerThread.start(); 2288 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2289 mProcessLoggingHandler = new ProcessLoggingHandler(); 2290 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2291 2292 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 2293 mInstantAppRegistry = new InstantAppRegistry(this); 2294 2295 File dataDir = Environment.getDataDirectory(); 2296 mAppInstallDir = new File(dataDir, "app"); 2297 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2298 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2299 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2300 sUserManager = new UserManagerService(context, this, 2301 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages); 2302 2303 // Propagate permission configuration in to package manager. 2304 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2305 = systemConfig.getPermissions(); 2306 for (int i=0; i<permConfig.size(); i++) { 2307 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2308 BasePermission bp = mSettings.mPermissions.get(perm.name); 2309 if (bp == null) { 2310 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2311 mSettings.mPermissions.put(perm.name, bp); 2312 } 2313 if (perm.gids != null) { 2314 bp.setGids(perm.gids, perm.perUser); 2315 } 2316 } 2317 2318 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2319 final int builtInLibCount = libConfig.size(); 2320 for (int i = 0; i < builtInLibCount; i++) { 2321 String name = libConfig.keyAt(i); 2322 String path = libConfig.valueAt(i); 2323 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED, 2324 SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0); 2325 } 2326 2327 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2328 2329 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings"); 2330 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2331 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2332 2333 // Clean up orphaned packages for which the code path doesn't exist 2334 // and they are an update to a system app - caused by bug/32321269 2335 final int packageSettingCount = mSettings.mPackages.size(); 2336 for (int i = packageSettingCount - 1; i >= 0; i--) { 2337 PackageSetting ps = mSettings.mPackages.valueAt(i); 2338 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists()) 2339 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) { 2340 mSettings.mPackages.removeAt(i); 2341 mSettings.enableSystemPackageLPw(ps.name); 2342 } 2343 } 2344 2345 if (mFirstBoot) { 2346 requestCopyPreoptedFiles(); 2347 } 2348 2349 String customResolverActivity = Resources.getSystem().getString( 2350 R.string.config_customResolverActivity); 2351 if (TextUtils.isEmpty(customResolverActivity)) { 2352 customResolverActivity = null; 2353 } else { 2354 mCustomResolverComponentName = ComponentName.unflattenFromString( 2355 customResolverActivity); 2356 } 2357 2358 long startTime = SystemClock.uptimeMillis(); 2359 2360 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2361 startTime); 2362 2363 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2364 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2365 2366 if (bootClassPath == null) { 2367 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2368 } 2369 2370 if (systemServerClassPath == null) { 2371 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2372 } 2373 2374 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2375 final String[] dexCodeInstructionSets = 2376 getDexCodeInstructionSets( 2377 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2378 2379 /** 2380 * Ensure all external libraries have had dexopt run on them. 2381 */ 2382 if (mSharedLibraries.size() > 0) { 2383 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 2384 // NOTE: For now, we're compiling these system "shared libraries" 2385 // (and framework jars) into all available architectures. It's possible 2386 // to compile them only when we come across an app that uses them (there's 2387 // already logic for that in scanPackageLI) but that adds some complexity. 2388 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2389 final int libCount = mSharedLibraries.size(); 2390 for (int i = 0; i < libCount; i++) { 2391 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 2392 final int versionCount = versionedLib.size(); 2393 for (int j = 0; j < versionCount; j++) { 2394 SharedLibraryEntry libEntry = versionedLib.valueAt(j); 2395 final String libPath = libEntry.path != null 2396 ? libEntry.path : libEntry.apk; 2397 if (libPath == null) { 2398 continue; 2399 } 2400 try { 2401 // Shared libraries do not have profiles so we perform a full 2402 // AOT compilation (if needed). 2403 int dexoptNeeded = DexFile.getDexOptNeeded( 2404 libPath, dexCodeInstructionSet, 2405 getCompilerFilterForReason(REASON_SHARED_APK), 2406 false /* newProfile */); 2407 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2408 mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*", 2409 dexCodeInstructionSet, dexoptNeeded, null, 2410 DEXOPT_PUBLIC, 2411 getCompilerFilterForReason(REASON_SHARED_APK), 2412 StorageManager.UUID_PRIVATE_INTERNAL, 2413 PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK); 2414 } 2415 } catch (FileNotFoundException e) { 2416 Slog.w(TAG, "Library not found: " + libPath); 2417 } catch (IOException | InstallerException e) { 2418 Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? " 2419 + e.getMessage()); 2420 } 2421 } 2422 } 2423 } 2424 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2425 } 2426 2427 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2428 2429 final VersionInfo ver = mSettings.getInternalVersion(); 2430 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2431 2432 // when upgrading from pre-M, promote system app permissions from install to runtime 2433 mPromoteSystemApps = 2434 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2435 2436 // When upgrading from pre-N, we need to handle package extraction like first boot, 2437 // as there is no profiling data available. 2438 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2439 2440 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1; 2441 2442 // save off the names of pre-existing system packages prior to scanning; we don't 2443 // want to automatically grant runtime permissions for new system apps 2444 if (mPromoteSystemApps) { 2445 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2446 while (pkgSettingIter.hasNext()) { 2447 PackageSetting ps = pkgSettingIter.next(); 2448 if (isSystemApp(ps)) { 2449 mExistingSystemPackages.add(ps.name); 2450 } 2451 } 2452 } 2453 2454 mCacheDir = preparePackageParserCache(mIsUpgrade); 2455 2456 // Set flag to monitor and not change apk file paths when 2457 // scanning install directories. 2458 int scanFlags = SCAN_BOOTING | SCAN_INITIAL; 2459 2460 if (mIsUpgrade || mFirstBoot) { 2461 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE; 2462 } 2463 2464 // Collect vendor overlay packages. (Do this before scanning any apps.) 2465 // For security and version matching reason, only consider 2466 // overlay packages if they reside in the right directory. 2467 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags 2468 | PackageParser.PARSE_IS_SYSTEM 2469 | PackageParser.PARSE_IS_SYSTEM_DIR 2470 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2471 2472 // Find base frameworks (resource packages without code). 2473 scanDirTracedLI(frameworkDir, mDefParseFlags 2474 | PackageParser.PARSE_IS_SYSTEM 2475 | PackageParser.PARSE_IS_SYSTEM_DIR 2476 | PackageParser.PARSE_IS_PRIVILEGED, 2477 scanFlags | SCAN_NO_DEX, 0); 2478 2479 // Collected privileged system packages. 2480 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2481 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2482 | PackageParser.PARSE_IS_SYSTEM 2483 | PackageParser.PARSE_IS_SYSTEM_DIR 2484 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2485 2486 // Collect ordinary system packages. 2487 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2488 scanDirTracedLI(systemAppDir, mDefParseFlags 2489 | PackageParser.PARSE_IS_SYSTEM 2490 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2491 2492 // Collect all vendor packages. 2493 File vendorAppDir = new File("/vendor/app"); 2494 try { 2495 vendorAppDir = vendorAppDir.getCanonicalFile(); 2496 } catch (IOException e) { 2497 // failed to look up canonical path, continue with original one 2498 } 2499 scanDirTracedLI(vendorAppDir, mDefParseFlags 2500 | PackageParser.PARSE_IS_SYSTEM 2501 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2502 2503 // Collect all OEM packages. 2504 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2505 scanDirTracedLI(oemAppDir, mDefParseFlags 2506 | PackageParser.PARSE_IS_SYSTEM 2507 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2508 2509 // Prune any system packages that no longer exist. 2510 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2511 if (!mOnlyCore) { 2512 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2513 while (psit.hasNext()) { 2514 PackageSetting ps = psit.next(); 2515 2516 /* 2517 * If this is not a system app, it can't be a 2518 * disable system app. 2519 */ 2520 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2521 continue; 2522 } 2523 2524 /* 2525 * If the package is scanned, it's not erased. 2526 */ 2527 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2528 if (scannedPkg != null) { 2529 /* 2530 * If the system app is both scanned and in the 2531 * disabled packages list, then it must have been 2532 * added via OTA. Remove it from the currently 2533 * scanned package so the previously user-installed 2534 * application can be scanned. 2535 */ 2536 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2537 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2538 + ps.name + "; removing system app. Last known codePath=" 2539 + ps.codePathString + ", installStatus=" + ps.installStatus 2540 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2541 + scannedPkg.mVersionCode); 2542 removePackageLI(scannedPkg, true); 2543 mExpectingBetter.put(ps.name, ps.codePath); 2544 } 2545 2546 continue; 2547 } 2548 2549 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2550 psit.remove(); 2551 logCriticalInfo(Log.WARN, "System package " + ps.name 2552 + " no longer exists; it's data will be wiped"); 2553 // Actual deletion of code and data will be handled by later 2554 // reconciliation step 2555 } else { 2556 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2557 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2558 possiblyDeletedUpdatedSystemApps.add(ps.name); 2559 } 2560 } 2561 } 2562 } 2563 2564 //look for any incomplete package installations 2565 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2566 for (int i = 0; i < deletePkgsList.size(); i++) { 2567 // Actual deletion of code and data will be handled by later 2568 // reconciliation step 2569 final String packageName = deletePkgsList.get(i).name; 2570 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2571 synchronized (mPackages) { 2572 mSettings.removePackageLPw(packageName); 2573 } 2574 } 2575 2576 //delete tmp files 2577 deleteTempPackageFiles(); 2578 2579 // Remove any shared userIDs that have no associated packages 2580 mSettings.pruneSharedUsersLPw(); 2581 2582 if (!mOnlyCore) { 2583 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2584 SystemClock.uptimeMillis()); 2585 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2586 2587 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2588 | PackageParser.PARSE_FORWARD_LOCK, 2589 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2590 2591 /** 2592 * Remove disable package settings for any updated system 2593 * apps that were removed via an OTA. If they're not a 2594 * previously-updated app, remove them completely. 2595 * Otherwise, just revoke their system-level permissions. 2596 */ 2597 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2598 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2599 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2600 2601 String msg; 2602 if (deletedPkg == null) { 2603 msg = "Updated system package " + deletedAppName 2604 + " no longer exists; it's data will be wiped"; 2605 // Actual deletion of code and data will be handled by later 2606 // reconciliation step 2607 } else { 2608 msg = "Updated system app + " + deletedAppName 2609 + " no longer present; removing system privileges for " 2610 + deletedAppName; 2611 2612 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2613 2614 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2615 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2616 } 2617 logCriticalInfo(Log.WARN, msg); 2618 } 2619 2620 /** 2621 * Make sure all system apps that we expected to appear on 2622 * the userdata partition actually showed up. If they never 2623 * appeared, crawl back and revive the system version. 2624 */ 2625 for (int i = 0; i < mExpectingBetter.size(); i++) { 2626 final String packageName = mExpectingBetter.keyAt(i); 2627 if (!mPackages.containsKey(packageName)) { 2628 final File scanFile = mExpectingBetter.valueAt(i); 2629 2630 logCriticalInfo(Log.WARN, "Expected better " + packageName 2631 + " but never showed up; reverting to system"); 2632 2633 int reparseFlags = mDefParseFlags; 2634 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2635 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2636 | PackageParser.PARSE_IS_SYSTEM_DIR 2637 | PackageParser.PARSE_IS_PRIVILEGED; 2638 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2639 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2640 | PackageParser.PARSE_IS_SYSTEM_DIR; 2641 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2642 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2643 | PackageParser.PARSE_IS_SYSTEM_DIR; 2644 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2645 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2646 | PackageParser.PARSE_IS_SYSTEM_DIR; 2647 } else { 2648 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2649 continue; 2650 } 2651 2652 mSettings.enableSystemPackageLPw(packageName); 2653 2654 try { 2655 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2656 } catch (PackageManagerException e) { 2657 Slog.e(TAG, "Failed to parse original system package: " 2658 + e.getMessage()); 2659 } 2660 } 2661 } 2662 } 2663 mExpectingBetter.clear(); 2664 2665 // Resolve the storage manager. 2666 mStorageManagerPackage = getStorageManagerPackageName(); 2667 2668 // Resolve protected action filters. Only the setup wizard is allowed to 2669 // have a high priority filter for these actions. 2670 mSetupWizardPackage = getSetupWizardPackageName(); 2671 if (mProtectedFilters.size() > 0) { 2672 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2673 Slog.i(TAG, "No setup wizard;" 2674 + " All protected intents capped to priority 0"); 2675 } 2676 for (ActivityIntentInfo filter : mProtectedFilters) { 2677 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2678 if (DEBUG_FILTERS) { 2679 Slog.i(TAG, "Found setup wizard;" 2680 + " allow priority " + filter.getPriority() + ";" 2681 + " package: " + filter.activity.info.packageName 2682 + " activity: " + filter.activity.className 2683 + " priority: " + filter.getPriority()); 2684 } 2685 // skip setup wizard; allow it to keep the high priority filter 2686 continue; 2687 } 2688 Slog.w(TAG, "Protected action; cap priority to 0;" 2689 + " package: " + filter.activity.info.packageName 2690 + " activity: " + filter.activity.className 2691 + " origPrio: " + filter.getPriority()); 2692 filter.setPriority(0); 2693 } 2694 } 2695 mDeferProtectedFilters = false; 2696 mProtectedFilters.clear(); 2697 2698 // Now that we know all of the shared libraries, update all clients to have 2699 // the correct library paths. 2700 updateAllSharedLibrariesLPw(null); 2701 2702 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2703 // NOTE: We ignore potential failures here during a system scan (like 2704 // the rest of the commands above) because there's precious little we 2705 // can do about it. A settings error is reported, though. 2706 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/); 2707 } 2708 2709 // Now that we know all the packages we are keeping, 2710 // read and update their last usage times. 2711 mPackageUsage.read(mPackages); 2712 mCompilerStats.read(); 2713 2714 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2715 SystemClock.uptimeMillis()); 2716 Slog.i(TAG, "Time to scan packages: " 2717 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2718 + " seconds"); 2719 2720 // If the platform SDK has changed since the last time we booted, 2721 // we need to re-grant app permission to catch any new ones that 2722 // appear. This is really a hack, and means that apps can in some 2723 // cases get permissions that the user didn't initially explicitly 2724 // allow... it would be nice to have some better way to handle 2725 // this situation. 2726 int updateFlags = UPDATE_PERMISSIONS_ALL; 2727 if (ver.sdkVersion != mSdkVersion) { 2728 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2729 + mSdkVersion + "; regranting permissions for internal storage"); 2730 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2731 } 2732 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2733 ver.sdkVersion = mSdkVersion; 2734 2735 // If this is the first boot or an update from pre-M, and it is a normal 2736 // boot, then we need to initialize the default preferred apps across 2737 // all defined users. 2738 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2739 for (UserInfo user : sUserManager.getUsers(true)) { 2740 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2741 applyFactoryDefaultBrowserLPw(user.id); 2742 primeDomainVerificationsLPw(user.id); 2743 } 2744 } 2745 2746 // Prepare storage for system user really early during boot, 2747 // since core system apps like SettingsProvider and SystemUI 2748 // can't wait for user to start 2749 final int storageFlags; 2750 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2751 storageFlags = StorageManager.FLAG_STORAGE_DE; 2752 } else { 2753 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2754 } 2755 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, 2756 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */, 2757 true /* onlyCoreApps */); 2758 mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> { 2759 if (deferPackages == null || deferPackages.isEmpty()) { 2760 return; 2761 } 2762 int count = 0; 2763 for (String pkgName : deferPackages) { 2764 PackageParser.Package pkg = null; 2765 synchronized (mPackages) { 2766 PackageSetting ps = mSettings.getPackageLPr(pkgName); 2767 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) { 2768 pkg = ps.pkg; 2769 } 2770 } 2771 if (pkg != null) { 2772 synchronized (mInstallLock) { 2773 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags, 2774 true /* maybeMigrateAppData */); 2775 } 2776 count++; 2777 } 2778 } 2779 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages"); 2780 }, "prepareAppData"); 2781 2782 // If this is first boot after an OTA, and a normal boot, then 2783 // we need to clear code cache directories. 2784 // Note that we do *not* clear the application profiles. These remain valid 2785 // across OTAs and are used to drive profile verification (post OTA) and 2786 // profile compilation (without waiting to collect a fresh set of profiles). 2787 if (mIsUpgrade && !onlyCore) { 2788 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2789 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2790 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2791 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2792 // No apps are running this early, so no need to freeze 2793 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2794 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2795 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2796 } 2797 } 2798 ver.fingerprint = Build.FINGERPRINT; 2799 } 2800 2801 checkDefaultBrowser(); 2802 2803 // clear only after permissions and other defaults have been updated 2804 mExistingSystemPackages.clear(); 2805 mPromoteSystemApps = false; 2806 2807 // All the changes are done during package scanning. 2808 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2809 2810 // can downgrade to reader 2811 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings"); 2812 mSettings.writeLPr(); 2813 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2814 2815 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2816 // early on (before the package manager declares itself as early) because other 2817 // components in the system server might ask for package contexts for these apps. 2818 // 2819 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2820 // (i.e, that the data partition is unavailable). 2821 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2822 long start = System.nanoTime(); 2823 List<PackageParser.Package> coreApps = new ArrayList<>(); 2824 for (PackageParser.Package pkg : mPackages.values()) { 2825 if (pkg.coreApp) { 2826 coreApps.add(pkg); 2827 } 2828 } 2829 2830 int[] stats = performDexOptUpgrade(coreApps, false, 2831 getCompilerFilterForReason(REASON_CORE_APP)); 2832 2833 final int elapsedTimeSeconds = 2834 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2835 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2836 2837 if (DEBUG_DEXOPT) { 2838 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2839 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2840 } 2841 2842 2843 // TODO: Should we log these stats to tron too ? 2844 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2845 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2846 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2847 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2848 } 2849 2850 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2851 SystemClock.uptimeMillis()); 2852 2853 if (!mOnlyCore) { 2854 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2855 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2856 mRequiredUninstallerPackage = getRequiredUninstallerLPr(); 2857 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2858 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2859 mIntentFilterVerifierComponent); 2860 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2861 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES, 2862 SharedLibraryInfo.VERSION_UNDEFINED); 2863 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2864 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED, 2865 SharedLibraryInfo.VERSION_UNDEFINED); 2866 } else { 2867 mRequiredVerifierPackage = null; 2868 mRequiredInstallerPackage = null; 2869 mRequiredUninstallerPackage = null; 2870 mIntentFilterVerifierComponent = null; 2871 mIntentFilterVerifier = null; 2872 mServicesSystemSharedLibraryPackageName = null; 2873 mSharedSystemSharedLibraryPackageName = null; 2874 } 2875 2876 mInstallerService = new PackageInstallerService(context, this); 2877 2878 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2879 if (ephemeralResolverComponent != null) { 2880 if (DEBUG_EPHEMERAL) { 2881 Slog.i(TAG, "Ephemeral resolver: " + ephemeralResolverComponent); 2882 } 2883 mInstantAppResolverConnection = 2884 new EphemeralResolverConnection(mContext, ephemeralResolverComponent); 2885 } else { 2886 mInstantAppResolverConnection = null; 2887 } 2888 mInstantAppInstallerComponent = getEphemeralInstallerLPr(); 2889 if (mInstantAppInstallerComponent != null) { 2890 if (DEBUG_EPHEMERAL) { 2891 Slog.i(TAG, "Ephemeral installer: " + mInstantAppInstallerComponent); 2892 } 2893 setUpInstantAppInstallerActivityLP(mInstantAppInstallerComponent); 2894 } 2895 2896 // Read and update the usage of dex files. 2897 // Do this at the end of PM init so that all the packages have their 2898 // data directory reconciled. 2899 // At this point we know the code paths of the packages, so we can validate 2900 // the disk file and build the internal cache. 2901 // The usage file is expected to be small so loading and verifying it 2902 // should take a fairly small time compare to the other activities (e.g. package 2903 // scanning). 2904 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>(); 2905 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 2906 for (int userId : currentUserIds) { 2907 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList()); 2908 } 2909 mDexManager.load(userPackages); 2910 } // synchronized (mPackages) 2911 } // synchronized (mInstallLock) 2912 2913 // Now after opening every single application zip, make sure they 2914 // are all flushed. Not really needed, but keeps things nice and 2915 // tidy. 2916 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC"); 2917 Runtime.getRuntime().gc(); 2918 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2919 2920 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks"); 2921 FallbackCategoryProvider.loadFallbacks(); 2922 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2923 2924 // The initial scanning above does many calls into installd while 2925 // holding the mPackages lock, but we're mostly interested in yelling 2926 // once we have a booted system. 2927 mInstaller.setWarnIfHeld(mPackages); 2928 2929 // Expose private service for system components to use. 2930 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2931 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2932 } 2933 2934 private static File preparePackageParserCache(boolean isUpgrade) { 2935 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { 2936 return null; 2937 } 2938 2939 // Disable package parsing on eng builds to allow for faster incremental development. 2940 if ("eng".equals(Build.TYPE)) { 2941 return null; 2942 } 2943 2944 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) { 2945 Slog.i(TAG, "Disabling package parser cache due to system property."); 2946 return null; 2947 } 2948 2949 // The base directory for the package parser cache lives under /data/system/. 2950 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(), 2951 "package_cache"); 2952 if (cacheBaseDir == null) { 2953 return null; 2954 } 2955 2956 // If this is a system upgrade scenario, delete the contents of the package cache dir. 2957 // This also serves to "GC" unused entries when the package cache version changes (which 2958 // can only happen during upgrades). 2959 if (isUpgrade) { 2960 FileUtils.deleteContents(cacheBaseDir); 2961 } 2962 2963 2964 // Return the versioned package cache directory. This is something like 2965 // "/data/system/package_cache/1" 2966 File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); 2967 2968 // The following is a workaround to aid development on non-numbered userdebug 2969 // builds or cases where "adb sync" is used on userdebug builds. If we detect that 2970 // the system partition is newer. 2971 // 2972 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build 2973 // that starts with "eng." to signify that this is an engineering build and not 2974 // destined for release. 2975 if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) { 2976 Slog.w(TAG, "Wiping cache directory because the system partition changed."); 2977 2978 // Heuristic: If the /system directory has been modified recently due to an "adb sync" 2979 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable 2980 // in general and should not be used for production changes. In this specific case, 2981 // we know that they will work. 2982 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2983 if (cacheDir.lastModified() < frameworkDir.lastModified()) { 2984 FileUtils.deleteContents(cacheBaseDir); 2985 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); 2986 } 2987 } 2988 2989 return cacheDir; 2990 } 2991 2992 @Override 2993 public boolean isFirstBoot() { 2994 return mFirstBoot; 2995 } 2996 2997 @Override 2998 public boolean isOnlyCoreApps() { 2999 return mOnlyCore; 3000 } 3001 3002 @Override 3003 public boolean isUpgrade() { 3004 return mIsUpgrade; 3005 } 3006 3007 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 3008 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 3009 3010 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 3011 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3012 UserHandle.USER_SYSTEM); 3013 if (matches.size() == 1) { 3014 return matches.get(0).getComponentInfo().packageName; 3015 } else if (matches.size() == 0) { 3016 Log.e(TAG, "There should probably be a verifier, but, none were found"); 3017 return null; 3018 } 3019 throw new RuntimeException("There must be exactly one verifier; found " + matches); 3020 } 3021 3022 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) { 3023 synchronized (mPackages) { 3024 SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version); 3025 if (libraryEntry == null) { 3026 throw new IllegalStateException("Missing required shared library:" + name); 3027 } 3028 return libraryEntry.apk; 3029 } 3030 } 3031 3032 private @NonNull String getRequiredInstallerLPr() { 3033 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 3034 intent.addCategory(Intent.CATEGORY_DEFAULT); 3035 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 3036 3037 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 3038 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3039 UserHandle.USER_SYSTEM); 3040 if (matches.size() == 1) { 3041 ResolveInfo resolveInfo = matches.get(0); 3042 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 3043 throw new RuntimeException("The installer must be a privileged app"); 3044 } 3045 return matches.get(0).getComponentInfo().packageName; 3046 } else { 3047 throw new RuntimeException("There must be exactly one installer; found " + matches); 3048 } 3049 } 3050 3051 private @NonNull String getRequiredUninstallerLPr() { 3052 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 3053 intent.addCategory(Intent.CATEGORY_DEFAULT); 3054 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null)); 3055 3056 final ResolveInfo resolveInfo = resolveIntent(intent, null, 3057 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3058 UserHandle.USER_SYSTEM); 3059 if (resolveInfo == null || 3060 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) { 3061 throw new RuntimeException("There must be exactly one uninstaller; found " 3062 + resolveInfo); 3063 } 3064 return resolveInfo.getComponentInfo().packageName; 3065 } 3066 3067 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 3068 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 3069 3070 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 3071 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3072 UserHandle.USER_SYSTEM); 3073 ResolveInfo best = null; 3074 final int N = matches.size(); 3075 for (int i = 0; i < N; i++) { 3076 final ResolveInfo cur = matches.get(i); 3077 final String packageName = cur.getComponentInfo().packageName; 3078 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 3079 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 3080 continue; 3081 } 3082 3083 if (best == null || cur.priority > best.priority) { 3084 best = cur; 3085 } 3086 } 3087 3088 if (best != null) { 3089 return best.getComponentInfo().getComponentName(); 3090 } else { 3091 throw new RuntimeException("There must be at least one intent filter verifier"); 3092 } 3093 } 3094 3095 private @Nullable ComponentName getEphemeralResolverLPr() { 3096 final String[] packageArray = 3097 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 3098 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 3099 if (DEBUG_EPHEMERAL) { 3100 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 3101 } 3102 return null; 3103 } 3104 3105 final int resolveFlags = 3106 MATCH_DIRECT_BOOT_AWARE 3107 | MATCH_DIRECT_BOOT_UNAWARE 3108 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 3109 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 3110 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 3111 resolveFlags, UserHandle.USER_SYSTEM); 3112 3113 final int N = resolvers.size(); 3114 if (N == 0) { 3115 if (DEBUG_EPHEMERAL) { 3116 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 3117 } 3118 return null; 3119 } 3120 3121 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 3122 for (int i = 0; i < N; i++) { 3123 final ResolveInfo info = resolvers.get(i); 3124 3125 if (info.serviceInfo == null) { 3126 continue; 3127 } 3128 3129 final String packageName = info.serviceInfo.packageName; 3130 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 3131 if (DEBUG_EPHEMERAL) { 3132 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 3133 + " pkg: " + packageName + ", info:" + info); 3134 } 3135 continue; 3136 } 3137 3138 if (DEBUG_EPHEMERAL) { 3139 Slog.v(TAG, "Ephemeral resolver found;" 3140 + " pkg: " + packageName + ", info:" + info); 3141 } 3142 return new ComponentName(packageName, info.serviceInfo.name); 3143 } 3144 if (DEBUG_EPHEMERAL) { 3145 Slog.v(TAG, "Ephemeral resolver NOT found"); 3146 } 3147 return null; 3148 } 3149 3150 private @Nullable ComponentName getEphemeralInstallerLPr() { 3151 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 3152 intent.addCategory(Intent.CATEGORY_DEFAULT); 3153 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 3154 3155 final int resolveFlags = 3156 MATCH_DIRECT_BOOT_AWARE 3157 | MATCH_DIRECT_BOOT_UNAWARE 3158 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 3159 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 3160 resolveFlags, UserHandle.USER_SYSTEM); 3161 Iterator<ResolveInfo> iter = matches.iterator(); 3162 while (iter.hasNext()) { 3163 final ResolveInfo rInfo = iter.next(); 3164 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); 3165 if (ps != null) { 3166 final PermissionsState permissionsState = ps.getPermissionsState(); 3167 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) { 3168 continue; 3169 } 3170 } 3171 iter.remove(); 3172 } 3173 if (matches.size() == 0) { 3174 return null; 3175 } else if (matches.size() == 1) { 3176 return matches.get(0).getComponentInfo().getComponentName(); 3177 } else { 3178 throw new RuntimeException( 3179 "There must be at most one ephemeral installer; found " + matches); 3180 } 3181 } 3182 3183 private void primeDomainVerificationsLPw(int userId) { 3184 if (DEBUG_DOMAIN_VERIFICATION) { 3185 Slog.d(TAG, "Priming domain verifications in user " + userId); 3186 } 3187 3188 SystemConfig systemConfig = SystemConfig.getInstance(); 3189 ArraySet<String> packages = systemConfig.getLinkedApps(); 3190 3191 for (String packageName : packages) { 3192 PackageParser.Package pkg = mPackages.get(packageName); 3193 if (pkg != null) { 3194 if (!pkg.isSystemApp()) { 3195 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 3196 continue; 3197 } 3198 3199 ArraySet<String> domains = null; 3200 for (PackageParser.Activity a : pkg.activities) { 3201 for (ActivityIntentInfo filter : a.intents) { 3202 if (hasValidDomains(filter)) { 3203 if (domains == null) { 3204 domains = new ArraySet<String>(); 3205 } 3206 domains.addAll(filter.getHostsList()); 3207 } 3208 } 3209 } 3210 3211 if (domains != null && domains.size() > 0) { 3212 if (DEBUG_DOMAIN_VERIFICATION) { 3213 Slog.v(TAG, " + " + packageName); 3214 } 3215 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 3216 // state w.r.t. the formal app-linkage "no verification attempted" state; 3217 // and then 'always' in the per-user state actually used for intent resolution. 3218 final IntentFilterVerificationInfo ivi; 3219 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains); 3220 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 3221 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 3222 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 3223 } else { 3224 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 3225 + "' does not handle web links"); 3226 } 3227 } else { 3228 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 3229 } 3230 } 3231 3232 scheduleWritePackageRestrictionsLocked(userId); 3233 scheduleWriteSettingsLocked(); 3234 } 3235 3236 private void applyFactoryDefaultBrowserLPw(int userId) { 3237 // The default browser app's package name is stored in a string resource, 3238 // with a product-specific overlay used for vendor customization. 3239 String browserPkg = mContext.getResources().getString( 3240 com.android.internal.R.string.default_browser); 3241 if (!TextUtils.isEmpty(browserPkg)) { 3242 // non-empty string => required to be a known package 3243 PackageSetting ps = mSettings.mPackages.get(browserPkg); 3244 if (ps == null) { 3245 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 3246 browserPkg = null; 3247 } else { 3248 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3249 } 3250 } 3251 3252 // Nothing valid explicitly set? Make the factory-installed browser the explicit 3253 // default. If there's more than one, just leave everything alone. 3254 if (browserPkg == null) { 3255 calculateDefaultBrowserLPw(userId); 3256 } 3257 } 3258 3259 private void calculateDefaultBrowserLPw(int userId) { 3260 List<String> allBrowsers = resolveAllBrowserApps(userId); 3261 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 3262 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3263 } 3264 3265 private List<String> resolveAllBrowserApps(int userId) { 3266 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 3267 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3268 PackageManager.MATCH_ALL, userId); 3269 3270 final int count = list.size(); 3271 List<String> result = new ArrayList<String>(count); 3272 for (int i=0; i<count; i++) { 3273 ResolveInfo info = list.get(i); 3274 if (info.activityInfo == null 3275 || !info.handleAllWebDataURI 3276 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 3277 || result.contains(info.activityInfo.packageName)) { 3278 continue; 3279 } 3280 result.add(info.activityInfo.packageName); 3281 } 3282 3283 return result; 3284 } 3285 3286 private boolean packageIsBrowser(String packageName, int userId) { 3287 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3288 PackageManager.MATCH_ALL, userId); 3289 final int N = list.size(); 3290 for (int i = 0; i < N; i++) { 3291 ResolveInfo info = list.get(i); 3292 if (packageName.equals(info.activityInfo.packageName)) { 3293 return true; 3294 } 3295 } 3296 return false; 3297 } 3298 3299 private void checkDefaultBrowser() { 3300 final int myUserId = UserHandle.myUserId(); 3301 final String packageName = getDefaultBrowserPackageName(myUserId); 3302 if (packageName != null) { 3303 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 3304 if (info == null) { 3305 Slog.w(TAG, "Default browser no longer installed: " + packageName); 3306 synchronized (mPackages) { 3307 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 3308 } 3309 } 3310 } 3311 } 3312 3313 @Override 3314 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 3315 throws RemoteException { 3316 try { 3317 return super.onTransact(code, data, reply, flags); 3318 } catch (RuntimeException e) { 3319 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 3320 Slog.wtf(TAG, "Package Manager Crash", e); 3321 } 3322 throw e; 3323 } 3324 } 3325 3326 static int[] appendInts(int[] cur, int[] add) { 3327 if (add == null) return cur; 3328 if (cur == null) return add; 3329 final int N = add.length; 3330 for (int i=0; i<N; i++) { 3331 cur = appendInt(cur, add[i]); 3332 } 3333 return cur; 3334 } 3335 3336 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3337 if (!sUserManager.exists(userId)) return null; 3338 if (ps == null) { 3339 return null; 3340 } 3341 final PackageParser.Package p = ps.pkg; 3342 if (p == null) { 3343 return null; 3344 } 3345 // Filter out ephemeral app metadata: 3346 // * The system/shell/root can see metadata for any app 3347 // * An installed app can see metadata for 1) other installed apps 3348 // and 2) ephemeral apps that have explicitly interacted with it 3349 // * Ephemeral apps can only see their own metadata 3350 // * Holding a signature permission allows seeing instant apps 3351 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); 3352 if (callingAppId != Process.SYSTEM_UID 3353 && callingAppId != Process.SHELL_UID 3354 && callingAppId != Process.ROOT_UID 3355 && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS, 3356 Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) { 3357 final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid()); 3358 if (instantAppPackageName != null) { 3359 // ephemeral apps can only get information on themselves 3360 if (!instantAppPackageName.equals(p.packageName)) { 3361 return null; 3362 } 3363 } else { 3364 if (ps.getInstantApp(userId)) { 3365 // only get access to the ephemeral app if we've been granted access 3366 if (!mInstantAppRegistry.isInstantAccessGranted( 3367 userId, callingAppId, ps.appId)) { 3368 return null; 3369 } 3370 } 3371 } 3372 } 3373 3374 final PermissionsState permissionsState = ps.getPermissionsState(); 3375 3376 // Compute GIDs only if requested 3377 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3378 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3379 // Compute granted permissions only if package has requested permissions 3380 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3381 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3382 final PackageUserState state = ps.readUserState(userId); 3383 3384 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 3385 && ps.isSystem()) { 3386 flags |= MATCH_ANY_USER; 3387 } 3388 3389 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, 3390 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3391 3392 if (packageInfo == null) { 3393 return null; 3394 } 3395 3396 rebaseEnabledOverlays(packageInfo.applicationInfo, userId); 3397 3398 packageInfo.packageName = packageInfo.applicationInfo.packageName = 3399 resolveExternalPackageNameLPr(p); 3400 3401 return packageInfo; 3402 } 3403 3404 @Override 3405 public void checkPackageStartable(String packageName, int userId) { 3406 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3407 3408 synchronized (mPackages) { 3409 final PackageSetting ps = mSettings.mPackages.get(packageName); 3410 if (ps == null) { 3411 throw new SecurityException("Package " + packageName + " was not found!"); 3412 } 3413 3414 if (!ps.getInstalled(userId)) { 3415 throw new SecurityException( 3416 "Package " + packageName + " was not installed for user " + userId + "!"); 3417 } 3418 3419 if (mSafeMode && !ps.isSystem()) { 3420 throw new SecurityException("Package " + packageName + " not a system app!"); 3421 } 3422 3423 if (mFrozenPackages.contains(packageName)) { 3424 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3425 } 3426 3427 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3428 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3429 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3430 } 3431 } 3432 } 3433 3434 @Override 3435 public boolean isPackageAvailable(String packageName, int userId) { 3436 if (!sUserManager.exists(userId)) return false; 3437 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3438 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3439 synchronized (mPackages) { 3440 PackageParser.Package p = mPackages.get(packageName); 3441 if (p != null) { 3442 final PackageSetting ps = (PackageSetting) p.mExtras; 3443 if (ps != null) { 3444 final PackageUserState state = ps.readUserState(userId); 3445 if (state != null) { 3446 return PackageParser.isAvailable(state); 3447 } 3448 } 3449 } 3450 } 3451 return false; 3452 } 3453 3454 @Override 3455 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3456 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST, 3457 flags, userId); 3458 } 3459 3460 @Override 3461 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage, 3462 int flags, int userId) { 3463 return getPackageInfoInternal(versionedPackage.getPackageName(), 3464 // TODO: We will change version code to long, so in the new API it is long 3465 (int) versionedPackage.getVersionCode(), flags, userId); 3466 } 3467 3468 private PackageInfo getPackageInfoInternal(String packageName, int versionCode, 3469 int flags, int userId) { 3470 if (!sUserManager.exists(userId)) return null; 3471 flags = updateFlagsForPackage(flags, userId, packageName); 3472 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3473 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3474 3475 // reader 3476 synchronized (mPackages) { 3477 // Normalize package name to handle renamed packages and static libs 3478 packageName = resolveInternalPackageNameLPr(packageName, versionCode); 3479 3480 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3481 if (matchFactoryOnly) { 3482 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3483 if (ps != null) { 3484 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3485 return null; 3486 } 3487 return generatePackageInfo(ps, flags, userId); 3488 } 3489 } 3490 3491 PackageParser.Package p = mPackages.get(packageName); 3492 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3493 return null; 3494 } 3495 if (DEBUG_PACKAGE_INFO) 3496 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3497 if (p != null) { 3498 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras, 3499 Binder.getCallingUid(), userId)) { 3500 return null; 3501 } 3502 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3503 } 3504 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) { 3505 final PackageSetting ps = mSettings.mPackages.get(packageName); 3506 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3507 return null; 3508 } 3509 return generatePackageInfo(ps, flags, userId); 3510 } 3511 } 3512 return null; 3513 } 3514 3515 3516 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) { 3517 // System/shell/root get to see all static libs 3518 final int appId = UserHandle.getAppId(uid); 3519 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID 3520 || appId == Process.ROOT_UID) { 3521 return false; 3522 } 3523 3524 // No package means no static lib as it is always on internal storage 3525 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) { 3526 return false; 3527 } 3528 3529 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName, 3530 ps.pkg.staticSharedLibVersion); 3531 if (libEntry == null) { 3532 return false; 3533 } 3534 3535 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 3536 final String[] uidPackageNames = getPackagesForUid(resolvedUid); 3537 if (uidPackageNames == null) { 3538 return true; 3539 } 3540 3541 for (String uidPackageName : uidPackageNames) { 3542 if (ps.name.equals(uidPackageName)) { 3543 return false; 3544 } 3545 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName); 3546 if (uidPs != null) { 3547 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries, 3548 libEntry.info.getName()); 3549 if (index < 0) { 3550 continue; 3551 } 3552 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) { 3553 return false; 3554 } 3555 } 3556 } 3557 return true; 3558 } 3559 3560 @Override 3561 public String[] currentToCanonicalPackageNames(String[] names) { 3562 String[] out = new String[names.length]; 3563 // reader 3564 synchronized (mPackages) { 3565 for (int i=names.length-1; i>=0; i--) { 3566 PackageSetting ps = mSettings.mPackages.get(names[i]); 3567 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3568 } 3569 } 3570 return out; 3571 } 3572 3573 @Override 3574 public String[] canonicalToCurrentPackageNames(String[] names) { 3575 String[] out = new String[names.length]; 3576 // reader 3577 synchronized (mPackages) { 3578 for (int i=names.length-1; i>=0; i--) { 3579 String cur = mSettings.getRenamedPackageLPr(names[i]); 3580 out[i] = cur != null ? cur : names[i]; 3581 } 3582 } 3583 return out; 3584 } 3585 3586 @Override 3587 public int getPackageUid(String packageName, int flags, int userId) { 3588 if (!sUserManager.exists(userId)) return -1; 3589 flags = updateFlagsForPackage(flags, userId, packageName); 3590 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3591 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3592 3593 // reader 3594 synchronized (mPackages) { 3595 final PackageParser.Package p = mPackages.get(packageName); 3596 if (p != null && p.isMatch(flags)) { 3597 return UserHandle.getUid(userId, p.applicationInfo.uid); 3598 } 3599 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3600 final PackageSetting ps = mSettings.mPackages.get(packageName); 3601 if (ps != null && ps.isMatch(flags)) { 3602 return UserHandle.getUid(userId, ps.appId); 3603 } 3604 } 3605 } 3606 3607 return -1; 3608 } 3609 3610 @Override 3611 public int[] getPackageGids(String packageName, int flags, int userId) { 3612 if (!sUserManager.exists(userId)) return null; 3613 flags = updateFlagsForPackage(flags, userId, packageName); 3614 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3615 false /* requireFullPermission */, false /* checkShell */, 3616 "getPackageGids"); 3617 3618 // reader 3619 synchronized (mPackages) { 3620 final PackageParser.Package p = mPackages.get(packageName); 3621 if (p != null && p.isMatch(flags)) { 3622 PackageSetting ps = (PackageSetting) p.mExtras; 3623 // TODO: Shouldn't this be checking for package installed state for userId and 3624 // return null? 3625 return ps.getPermissionsState().computeGids(userId); 3626 } 3627 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3628 final PackageSetting ps = mSettings.mPackages.get(packageName); 3629 if (ps != null && ps.isMatch(flags)) { 3630 return ps.getPermissionsState().computeGids(userId); 3631 } 3632 } 3633 } 3634 3635 return null; 3636 } 3637 3638 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3639 if (bp.perm != null) { 3640 return PackageParser.generatePermissionInfo(bp.perm, flags); 3641 } 3642 PermissionInfo pi = new PermissionInfo(); 3643 pi.name = bp.name; 3644 pi.packageName = bp.sourcePackage; 3645 pi.nonLocalizedLabel = bp.name; 3646 pi.protectionLevel = bp.protectionLevel; 3647 return pi; 3648 } 3649 3650 @Override 3651 public PermissionInfo getPermissionInfo(String name, int flags) { 3652 // reader 3653 synchronized (mPackages) { 3654 final BasePermission p = mSettings.mPermissions.get(name); 3655 if (p != null) { 3656 return generatePermissionInfo(p, flags); 3657 } 3658 return null; 3659 } 3660 } 3661 3662 @Override 3663 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3664 int flags) { 3665 // reader 3666 synchronized (mPackages) { 3667 if (group != null && !mPermissionGroups.containsKey(group)) { 3668 // This is thrown as NameNotFoundException 3669 return null; 3670 } 3671 3672 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3673 for (BasePermission p : mSettings.mPermissions.values()) { 3674 if (group == null) { 3675 if (p.perm == null || p.perm.info.group == null) { 3676 out.add(generatePermissionInfo(p, flags)); 3677 } 3678 } else { 3679 if (p.perm != null && group.equals(p.perm.info.group)) { 3680 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3681 } 3682 } 3683 } 3684 return new ParceledListSlice<>(out); 3685 } 3686 } 3687 3688 @Override 3689 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3690 // reader 3691 synchronized (mPackages) { 3692 return PackageParser.generatePermissionGroupInfo( 3693 mPermissionGroups.get(name), flags); 3694 } 3695 } 3696 3697 @Override 3698 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3699 // reader 3700 synchronized (mPackages) { 3701 final int N = mPermissionGroups.size(); 3702 ArrayList<PermissionGroupInfo> out 3703 = new ArrayList<PermissionGroupInfo>(N); 3704 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3705 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3706 } 3707 return new ParceledListSlice<>(out); 3708 } 3709 } 3710 3711 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3712 int uid, int userId) { 3713 if (!sUserManager.exists(userId)) return null; 3714 PackageSetting ps = mSettings.mPackages.get(packageName); 3715 if (ps != null) { 3716 if (filterSharedLibPackageLPr(ps, uid, userId)) { 3717 return null; 3718 } 3719 if (ps.pkg == null) { 3720 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3721 if (pInfo != null) { 3722 return pInfo.applicationInfo; 3723 } 3724 return null; 3725 } 3726 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 3727 ps.readUserState(userId), userId); 3728 if (ai != null) { 3729 rebaseEnabledOverlays(ai, userId); 3730 ai.packageName = resolveExternalPackageNameLPr(ps.pkg); 3731 } 3732 return ai; 3733 } 3734 return null; 3735 } 3736 3737 @Override 3738 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3739 if (!sUserManager.exists(userId)) return null; 3740 flags = updateFlagsForApplication(flags, userId, packageName); 3741 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3742 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3743 3744 // writer 3745 synchronized (mPackages) { 3746 // Normalize package name to handle renamed packages and static libs 3747 packageName = resolveInternalPackageNameLPr(packageName, 3748 PackageManager.VERSION_CODE_HIGHEST); 3749 3750 PackageParser.Package p = mPackages.get(packageName); 3751 if (DEBUG_PACKAGE_INFO) Log.v( 3752 TAG, "getApplicationInfo " + packageName 3753 + ": " + p); 3754 if (p != null) { 3755 PackageSetting ps = mSettings.mPackages.get(packageName); 3756 if (ps == null) return null; 3757 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3758 return null; 3759 } 3760 // Note: isEnabledLP() does not apply here - always return info 3761 ApplicationInfo ai = PackageParser.generateApplicationInfo( 3762 p, flags, ps.readUserState(userId), userId); 3763 if (ai != null) { 3764 rebaseEnabledOverlays(ai, userId); 3765 ai.packageName = resolveExternalPackageNameLPr(p); 3766 } 3767 return ai; 3768 } 3769 if ("android".equals(packageName)||"system".equals(packageName)) { 3770 return mAndroidApplication; 3771 } 3772 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3773 // Already generates the external package name 3774 return generateApplicationInfoFromSettingsLPw(packageName, 3775 Binder.getCallingUid(), flags, userId); 3776 } 3777 } 3778 return null; 3779 } 3780 3781 private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) { 3782 List<String> paths = new ArrayList<>(); 3783 ArrayMap<String, ArrayList<String>> userSpecificOverlays = 3784 mEnabledOverlayPaths.get(userId); 3785 if (userSpecificOverlays != null) { 3786 if (!"android".equals(ai.packageName)) { 3787 ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android"); 3788 if (frameworkOverlays != null) { 3789 paths.addAll(frameworkOverlays); 3790 } 3791 } 3792 3793 ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName); 3794 if (appOverlays != null) { 3795 paths.addAll(appOverlays); 3796 } 3797 } 3798 ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null; 3799 } 3800 3801 private String normalizePackageNameLPr(String packageName) { 3802 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName); 3803 return normalizedPackageName != null ? normalizedPackageName : packageName; 3804 } 3805 3806 @Override 3807 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3808 final IPackageDataObserver observer) { 3809 mContext.enforceCallingOrSelfPermission( 3810 android.Manifest.permission.CLEAR_APP_CACHE, null); 3811 mHandler.post(() -> { 3812 boolean success = false; 3813 try { 3814 freeStorage(volumeUuid, freeStorageSize, 0); 3815 success = true; 3816 } catch (IOException e) { 3817 Slog.w(TAG, e); 3818 } 3819 if (observer != null) { 3820 try { 3821 observer.onRemoveCompleted(null, success); 3822 } catch (RemoteException e) { 3823 Slog.w(TAG, e); 3824 } 3825 } 3826 }); 3827 } 3828 3829 @Override 3830 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3831 final IntentSender pi) { 3832 mContext.enforceCallingOrSelfPermission( 3833 android.Manifest.permission.CLEAR_APP_CACHE, TAG); 3834 mHandler.post(() -> { 3835 boolean success = false; 3836 try { 3837 freeStorage(volumeUuid, freeStorageSize, 0); 3838 success = true; 3839 } catch (IOException e) { 3840 Slog.w(TAG, e); 3841 } 3842 if (pi != null) { 3843 try { 3844 pi.sendIntent(null, success ? 1 : 0, null, null, null); 3845 } catch (SendIntentException e) { 3846 Slog.w(TAG, e); 3847 } 3848 } 3849 }); 3850 } 3851 3852 /** 3853 * Blocking call to clear various types of cached data across the system 3854 * until the requested bytes are available. 3855 */ 3856 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException { 3857 final StorageManager storage = mContext.getSystemService(StorageManager.class); 3858 final File file = storage.findPathForUuid(volumeUuid); 3859 3860 if (ENABLE_FREE_CACHE_V2) { 3861 final boolean aggressive = (storageFlags 3862 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0; 3863 3864 // 1. Pre-flight to determine if we have any chance to succeed 3865 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive) 3866 3867 // 3. Consider parsed APK data (aggressive only) 3868 if (aggressive) { 3869 FileUtils.deleteContents(mCacheDir); 3870 } 3871 if (file.getUsableSpace() >= bytes) return; 3872 3873 // 4. Consider cached app data (above quotas) 3874 try { 3875 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2); 3876 } catch (InstallerException ignored) { 3877 } 3878 if (file.getUsableSpace() >= bytes) return; 3879 3880 // 5. Consider shared libraries with refcount=0 and age>2h 3881 // 6. Consider dexopt output (aggressive only) 3882 // 7. Consider ephemeral apps not used in last week 3883 3884 // 8. Consider cached app data (below quotas) 3885 try { 3886 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2 3887 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA); 3888 } catch (InstallerException ignored) { 3889 } 3890 if (file.getUsableSpace() >= bytes) return; 3891 3892 // 9. Consider DropBox entries 3893 // 10. Consider ephemeral cookies 3894 3895 } else { 3896 try { 3897 mInstaller.freeCache(volumeUuid, bytes, 0); 3898 } catch (InstallerException ignored) { 3899 } 3900 if (file.getUsableSpace() >= bytes) return; 3901 } 3902 3903 throw new IOException("Failed to free " + bytes + " on storage device at " + file); 3904 } 3905 3906 /** 3907 * Update given flags based on encryption status of current user. 3908 */ 3909 private int updateFlags(int flags, int userId) { 3910 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3911 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3912 // Caller expressed an explicit opinion about what encryption 3913 // aware/unaware components they want to see, so fall through and 3914 // give them what they want 3915 } else { 3916 // Caller expressed no opinion, so match based on user state 3917 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3918 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3919 } else { 3920 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3921 } 3922 } 3923 return flags; 3924 } 3925 3926 private UserManagerInternal getUserManagerInternal() { 3927 if (mUserManagerInternal == null) { 3928 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3929 } 3930 return mUserManagerInternal; 3931 } 3932 3933 private DeviceIdleController.LocalService getDeviceIdleController() { 3934 if (mDeviceIdleController == null) { 3935 mDeviceIdleController = 3936 LocalServices.getService(DeviceIdleController.LocalService.class); 3937 } 3938 return mDeviceIdleController; 3939 } 3940 3941 /** 3942 * Update given flags when being used to request {@link PackageInfo}. 3943 */ 3944 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3945 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM; 3946 boolean triaged = true; 3947 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3948 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3949 // Caller is asking for component details, so they'd better be 3950 // asking for specific encryption matching behavior, or be triaged 3951 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3952 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3953 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3954 triaged = false; 3955 } 3956 } 3957 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3958 | PackageManager.MATCH_SYSTEM_ONLY 3959 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3960 triaged = false; 3961 } 3962 if ((flags & PackageManager.MATCH_ANY_USER) != 0) { 3963 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 3964 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at " 3965 + Debug.getCallers(5)); 3966 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser 3967 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) { 3968 // If the caller wants all packages and has a restricted profile associated with it, 3969 // then match all users. This is to make sure that launchers that need to access work 3970 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using 3971 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380 3972 flags |= PackageManager.MATCH_ANY_USER; 3973 } 3974 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3975 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3976 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3977 } 3978 return updateFlags(flags, userId); 3979 } 3980 3981 /** 3982 * Update given flags when being used to request {@link ApplicationInfo}. 3983 */ 3984 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3985 return updateFlagsForPackage(flags, userId, cookie); 3986 } 3987 3988 /** 3989 * Update given flags when being used to request {@link ComponentInfo}. 3990 */ 3991 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3992 if (cookie instanceof Intent) { 3993 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3994 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3995 } 3996 } 3997 3998 boolean triaged = true; 3999 // Caller is asking for component details, so they'd better be 4000 // asking for specific encryption matching behavior, or be triaged 4001 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 4002 | PackageManager.MATCH_DIRECT_BOOT_AWARE 4003 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 4004 triaged = false; 4005 } 4006 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 4007 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 4008 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 4009 } 4010 4011 return updateFlags(flags, userId); 4012 } 4013 4014 /** 4015 * Update given intent when being used to request {@link ResolveInfo}. 4016 */ 4017 private Intent updateIntentForResolve(Intent intent) { 4018 if (intent.getSelector() != null) { 4019 intent = intent.getSelector(); 4020 } 4021 if (DEBUG_PREFERRED) { 4022 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4023 } 4024 return intent; 4025 } 4026 4027 /** 4028 * Update given flags when being used to request {@link ResolveInfo}. 4029 * <p>Instant apps are resolved specially, depending upon context. Minimally, 4030 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT} 4031 * flag set. However, this flag is only honoured in three circumstances: 4032 * <ul> 4033 * <li>when called from a system process</li> 4034 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li> 4035 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW} 4036 * action and a {@code android.intent.category.BROWSABLE} category</li> 4037 * </ul> 4038 */ 4039 int updateFlagsForResolve(int flags, int userId, Intent intent, boolean includeInstantApp) { 4040 // Safe mode means we shouldn't match any third-party components 4041 if (mSafeMode) { 4042 flags |= PackageManager.MATCH_SYSTEM_ONLY; 4043 } 4044 final int callingUid = Binder.getCallingUid(); 4045 if (getInstantAppPackageName(callingUid) != null) { 4046 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components 4047 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; 4048 flags |= PackageManager.MATCH_INSTANT; 4049 } else { 4050 // Otherwise, prevent leaking ephemeral components 4051 final boolean isSpecialProcess = 4052 callingUid == Process.SYSTEM_UID 4053 || callingUid == Process.SHELL_UID 4054 || callingUid == 0; 4055 final boolean allowMatchInstant = 4056 (includeInstantApp 4057 && Intent.ACTION_VIEW.equals(intent.getAction()) 4058 && intent.hasCategory(Intent.CATEGORY_BROWSABLE) 4059 && hasWebURI(intent)) 4060 || isSpecialProcess 4061 || mContext.checkCallingOrSelfPermission( 4062 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED; 4063 flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; 4064 if (!allowMatchInstant) { 4065 flags &= ~PackageManager.MATCH_INSTANT; 4066 } 4067 } 4068 return updateFlagsForComponent(flags, userId, intent /*cookie*/); 4069 } 4070 4071 @Override 4072 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 4073 if (!sUserManager.exists(userId)) return null; 4074 flags = updateFlagsForComponent(flags, userId, component); 4075 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4076 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 4077 synchronized (mPackages) { 4078 PackageParser.Activity a = mActivities.mActivities.get(component); 4079 4080 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 4081 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 4082 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4083 if (ps == null) return null; 4084 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 4085 userId); 4086 } 4087 if (mResolveComponentName.equals(component)) { 4088 return PackageParser.generateActivityInfo(mResolveActivity, flags, 4089 new PackageUserState(), userId); 4090 } 4091 } 4092 return null; 4093 } 4094 4095 @Override 4096 public boolean activitySupportsIntent(ComponentName component, Intent intent, 4097 String resolvedType) { 4098 synchronized (mPackages) { 4099 if (component.equals(mResolveComponentName)) { 4100 // The resolver supports EVERYTHING! 4101 return true; 4102 } 4103 PackageParser.Activity a = mActivities.mActivities.get(component); 4104 if (a == null) { 4105 return false; 4106 } 4107 for (int i=0; i<a.intents.size(); i++) { 4108 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 4109 intent.getData(), intent.getCategories(), TAG) >= 0) { 4110 return true; 4111 } 4112 } 4113 return false; 4114 } 4115 } 4116 4117 @Override 4118 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 4119 if (!sUserManager.exists(userId)) return null; 4120 flags = updateFlagsForComponent(flags, userId, component); 4121 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4122 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 4123 synchronized (mPackages) { 4124 PackageParser.Activity a = mReceivers.mActivities.get(component); 4125 if (DEBUG_PACKAGE_INFO) Log.v( 4126 TAG, "getReceiverInfo " + component + ": " + a); 4127 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 4128 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4129 if (ps == null) return null; 4130 ActivityInfo ri = PackageParser.generateActivityInfo(a, flags, 4131 ps.readUserState(userId), userId); 4132 if (ri != null) { 4133 rebaseEnabledOverlays(ri.applicationInfo, userId); 4134 } 4135 return ri; 4136 } 4137 } 4138 return null; 4139 } 4140 4141 @Override 4142 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) { 4143 if (!sUserManager.exists(userId)) return null; 4144 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0"); 4145 4146 flags = updateFlagsForPackage(flags, userId, null); 4147 4148 final boolean canSeeStaticLibraries = 4149 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES) 4150 == PERMISSION_GRANTED 4151 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES) 4152 == PERMISSION_GRANTED 4153 || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES) 4154 == PERMISSION_GRANTED 4155 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES) 4156 == PERMISSION_GRANTED; 4157 4158 synchronized (mPackages) { 4159 List<SharedLibraryInfo> result = null; 4160 4161 final int libCount = mSharedLibraries.size(); 4162 for (int i = 0; i < libCount; i++) { 4163 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 4164 if (versionedLib == null) { 4165 continue; 4166 } 4167 4168 final int versionCount = versionedLib.size(); 4169 for (int j = 0; j < versionCount; j++) { 4170 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info; 4171 if (!canSeeStaticLibraries && libInfo.isStatic()) { 4172 break; 4173 } 4174 final long identity = Binder.clearCallingIdentity(); 4175 try { 4176 // TODO: We will change version code to long, so in the new API it is long 4177 PackageInfo packageInfo = getPackageInfoVersioned( 4178 libInfo.getDeclaringPackage(), flags, userId); 4179 if (packageInfo == null) { 4180 continue; 4181 } 4182 } finally { 4183 Binder.restoreCallingIdentity(identity); 4184 } 4185 4186 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(), 4187 libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(), 4188 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId)); 4189 4190 if (result == null) { 4191 result = new ArrayList<>(); 4192 } 4193 result.add(resLibInfo); 4194 } 4195 } 4196 4197 return result != null ? new ParceledListSlice<>(result) : null; 4198 } 4199 } 4200 4201 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr( 4202 SharedLibraryInfo libInfo, int flags, int userId) { 4203 List<VersionedPackage> versionedPackages = null; 4204 final int packageCount = mSettings.mPackages.size(); 4205 for (int i = 0; i < packageCount; i++) { 4206 PackageSetting ps = mSettings.mPackages.valueAt(i); 4207 4208 if (ps == null) { 4209 continue; 4210 } 4211 4212 if (!ps.getUserState().get(userId).isAvailable(flags)) { 4213 continue; 4214 } 4215 4216 final String libName = libInfo.getName(); 4217 if (libInfo.isStatic()) { 4218 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName); 4219 if (libIdx < 0) { 4220 continue; 4221 } 4222 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) { 4223 continue; 4224 } 4225 if (versionedPackages == null) { 4226 versionedPackages = new ArrayList<>(); 4227 } 4228 // If the dependent is a static shared lib, use the public package name 4229 String dependentPackageName = ps.name; 4230 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) { 4231 dependentPackageName = ps.pkg.manifestPackageName; 4232 } 4233 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode)); 4234 } else if (ps.pkg != null) { 4235 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName) 4236 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) { 4237 if (versionedPackages == null) { 4238 versionedPackages = new ArrayList<>(); 4239 } 4240 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode)); 4241 } 4242 } 4243 } 4244 4245 return versionedPackages; 4246 } 4247 4248 @Override 4249 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 4250 if (!sUserManager.exists(userId)) return null; 4251 flags = updateFlagsForComponent(flags, userId, component); 4252 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4253 false /* requireFullPermission */, false /* checkShell */, "get service info"); 4254 synchronized (mPackages) { 4255 PackageParser.Service s = mServices.mServices.get(component); 4256 if (DEBUG_PACKAGE_INFO) Log.v( 4257 TAG, "getServiceInfo " + component + ": " + s); 4258 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 4259 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4260 if (ps == null) return null; 4261 ServiceInfo si = PackageParser.generateServiceInfo(s, flags, 4262 ps.readUserState(userId), userId); 4263 if (si != null) { 4264 rebaseEnabledOverlays(si.applicationInfo, userId); 4265 } 4266 return si; 4267 } 4268 } 4269 return null; 4270 } 4271 4272 @Override 4273 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 4274 if (!sUserManager.exists(userId)) return null; 4275 flags = updateFlagsForComponent(flags, userId, component); 4276 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4277 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 4278 synchronized (mPackages) { 4279 PackageParser.Provider p = mProviders.mProviders.get(component); 4280 if (DEBUG_PACKAGE_INFO) Log.v( 4281 TAG, "getProviderInfo " + component + ": " + p); 4282 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 4283 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4284 if (ps == null) return null; 4285 ProviderInfo pi = PackageParser.generateProviderInfo(p, flags, 4286 ps.readUserState(userId), userId); 4287 if (pi != null) { 4288 rebaseEnabledOverlays(pi.applicationInfo, userId); 4289 } 4290 return pi; 4291 } 4292 } 4293 return null; 4294 } 4295 4296 @Override 4297 public String[] getSystemSharedLibraryNames() { 4298 synchronized (mPackages) { 4299 Set<String> libs = null; 4300 final int libCount = mSharedLibraries.size(); 4301 for (int i = 0; i < libCount; i++) { 4302 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 4303 if (versionedLib == null) { 4304 continue; 4305 } 4306 final int versionCount = versionedLib.size(); 4307 for (int j = 0; j < versionCount; j++) { 4308 SharedLibraryEntry libEntry = versionedLib.valueAt(j); 4309 if (!libEntry.info.isStatic()) { 4310 if (libs == null) { 4311 libs = new ArraySet<>(); 4312 } 4313 libs.add(libEntry.info.getName()); 4314 break; 4315 } 4316 PackageSetting ps = mSettings.getPackageLPr(libEntry.apk); 4317 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(), 4318 UserHandle.getUserId(Binder.getCallingUid()))) { 4319 if (libs == null) { 4320 libs = new ArraySet<>(); 4321 } 4322 libs.add(libEntry.info.getName()); 4323 break; 4324 } 4325 } 4326 } 4327 4328 if (libs != null) { 4329 String[] libsArray = new String[libs.size()]; 4330 libs.toArray(libsArray); 4331 return libsArray; 4332 } 4333 4334 return null; 4335 } 4336 } 4337 4338 @Override 4339 public @NonNull String getServicesSystemSharedLibraryPackageName() { 4340 synchronized (mPackages) { 4341 return mServicesSystemSharedLibraryPackageName; 4342 } 4343 } 4344 4345 @Override 4346 public @NonNull String getSharedSystemSharedLibraryPackageName() { 4347 synchronized (mPackages) { 4348 return mSharedSystemSharedLibraryPackageName; 4349 } 4350 } 4351 4352 private void updateSequenceNumberLP(String packageName, int[] userList) { 4353 for (int i = userList.length - 1; i >= 0; --i) { 4354 final int userId = userList[i]; 4355 SparseArray<String> changedPackages = mChangedPackages.get(userId); 4356 if (changedPackages == null) { 4357 changedPackages = new SparseArray<>(); 4358 mChangedPackages.put(userId, changedPackages); 4359 } 4360 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId); 4361 if (sequenceNumbers == null) { 4362 sequenceNumbers = new HashMap<>(); 4363 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers); 4364 } 4365 final Integer sequenceNumber = sequenceNumbers.get(packageName); 4366 if (sequenceNumber != null) { 4367 changedPackages.remove(sequenceNumber); 4368 } 4369 changedPackages.put(mChangedPackagesSequenceNumber, packageName); 4370 sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber); 4371 } 4372 mChangedPackagesSequenceNumber++; 4373 } 4374 4375 @Override 4376 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) { 4377 synchronized (mPackages) { 4378 if (sequenceNumber >= mChangedPackagesSequenceNumber) { 4379 return null; 4380 } 4381 final SparseArray<String> changedPackages = mChangedPackages.get(userId); 4382 if (changedPackages == null) { 4383 return null; 4384 } 4385 final List<String> packageNames = 4386 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber); 4387 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) { 4388 final String packageName = changedPackages.get(i); 4389 if (packageName != null) { 4390 packageNames.add(packageName); 4391 } 4392 } 4393 return packageNames.isEmpty() 4394 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames); 4395 } 4396 } 4397 4398 @Override 4399 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 4400 ArrayList<FeatureInfo> res; 4401 synchronized (mAvailableFeatures) { 4402 res = new ArrayList<>(mAvailableFeatures.size() + 1); 4403 res.addAll(mAvailableFeatures.values()); 4404 } 4405 final FeatureInfo fi = new FeatureInfo(); 4406 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 4407 FeatureInfo.GL_ES_VERSION_UNDEFINED); 4408 res.add(fi); 4409 4410 return new ParceledListSlice<>(res); 4411 } 4412 4413 @Override 4414 public boolean hasSystemFeature(String name, int version) { 4415 synchronized (mAvailableFeatures) { 4416 final FeatureInfo feat = mAvailableFeatures.get(name); 4417 if (feat == null) { 4418 return false; 4419 } else { 4420 return feat.version >= version; 4421 } 4422 } 4423 } 4424 4425 @Override 4426 public int checkPermission(String permName, String pkgName, int userId) { 4427 if (!sUserManager.exists(userId)) { 4428 return PackageManager.PERMISSION_DENIED; 4429 } 4430 4431 synchronized (mPackages) { 4432 final PackageParser.Package p = mPackages.get(pkgName); 4433 if (p != null && p.mExtras != null) { 4434 final PackageSetting ps = (PackageSetting) p.mExtras; 4435 final PermissionsState permissionsState = ps.getPermissionsState(); 4436 if (permissionsState.hasPermission(permName, userId)) { 4437 return PackageManager.PERMISSION_GRANTED; 4438 } 4439 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 4440 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 4441 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 4442 return PackageManager.PERMISSION_GRANTED; 4443 } 4444 } 4445 } 4446 4447 return PackageManager.PERMISSION_DENIED; 4448 } 4449 4450 @Override 4451 public int checkUidPermission(String permName, int uid) { 4452 final int userId = UserHandle.getUserId(uid); 4453 4454 if (!sUserManager.exists(userId)) { 4455 return PackageManager.PERMISSION_DENIED; 4456 } 4457 4458 synchronized (mPackages) { 4459 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4460 if (obj != null) { 4461 final SettingBase ps = (SettingBase) obj; 4462 final PermissionsState permissionsState = ps.getPermissionsState(); 4463 if (permissionsState.hasPermission(permName, userId)) { 4464 return PackageManager.PERMISSION_GRANTED; 4465 } 4466 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 4467 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 4468 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 4469 return PackageManager.PERMISSION_GRANTED; 4470 } 4471 } else { 4472 ArraySet<String> perms = mSystemPermissions.get(uid); 4473 if (perms != null) { 4474 if (perms.contains(permName)) { 4475 return PackageManager.PERMISSION_GRANTED; 4476 } 4477 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 4478 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 4479 return PackageManager.PERMISSION_GRANTED; 4480 } 4481 } 4482 } 4483 } 4484 4485 return PackageManager.PERMISSION_DENIED; 4486 } 4487 4488 @Override 4489 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 4490 if (UserHandle.getCallingUserId() != userId) { 4491 mContext.enforceCallingPermission( 4492 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4493 "isPermissionRevokedByPolicy for user " + userId); 4494 } 4495 4496 if (checkPermission(permission, packageName, userId) 4497 == PackageManager.PERMISSION_GRANTED) { 4498 return false; 4499 } 4500 4501 final long identity = Binder.clearCallingIdentity(); 4502 try { 4503 final int flags = getPermissionFlags(permission, packageName, userId); 4504 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 4505 } finally { 4506 Binder.restoreCallingIdentity(identity); 4507 } 4508 } 4509 4510 @Override 4511 public String getPermissionControllerPackageName() { 4512 synchronized (mPackages) { 4513 return mRequiredInstallerPackage; 4514 } 4515 } 4516 4517 /** 4518 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 4519 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 4520 * @param checkShell whether to prevent shell from access if there's a debugging restriction 4521 * @param message the message to log on security exception 4522 */ 4523 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 4524 boolean checkShell, String message) { 4525 if (userId < 0) { 4526 throw new IllegalArgumentException("Invalid userId " + userId); 4527 } 4528 if (checkShell) { 4529 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 4530 } 4531 if (userId == UserHandle.getUserId(callingUid)) return; 4532 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4533 if (requireFullPermission) { 4534 mContext.enforceCallingOrSelfPermission( 4535 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 4536 } else { 4537 try { 4538 mContext.enforceCallingOrSelfPermission( 4539 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 4540 } catch (SecurityException se) { 4541 mContext.enforceCallingOrSelfPermission( 4542 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 4543 } 4544 } 4545 } 4546 } 4547 4548 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 4549 if (callingUid == Process.SHELL_UID) { 4550 if (userHandle >= 0 4551 && sUserManager.hasUserRestriction(restriction, userHandle)) { 4552 throw new SecurityException("Shell does not have permission to access user " 4553 + userHandle); 4554 } else if (userHandle < 0) { 4555 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 4556 + Debug.getCallers(3)); 4557 } 4558 } 4559 } 4560 4561 private BasePermission findPermissionTreeLP(String permName) { 4562 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 4563 if (permName.startsWith(bp.name) && 4564 permName.length() > bp.name.length() && 4565 permName.charAt(bp.name.length()) == '.') { 4566 return bp; 4567 } 4568 } 4569 return null; 4570 } 4571 4572 private BasePermission checkPermissionTreeLP(String permName) { 4573 if (permName != null) { 4574 BasePermission bp = findPermissionTreeLP(permName); 4575 if (bp != null) { 4576 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 4577 return bp; 4578 } 4579 throw new SecurityException("Calling uid " 4580 + Binder.getCallingUid() 4581 + " is not allowed to add to permission tree " 4582 + bp.name + " owned by uid " + bp.uid); 4583 } 4584 } 4585 throw new SecurityException("No permission tree found for " + permName); 4586 } 4587 4588 static boolean compareStrings(CharSequence s1, CharSequence s2) { 4589 if (s1 == null) { 4590 return s2 == null; 4591 } 4592 if (s2 == null) { 4593 return false; 4594 } 4595 if (s1.getClass() != s2.getClass()) { 4596 return false; 4597 } 4598 return s1.equals(s2); 4599 } 4600 4601 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 4602 if (pi1.icon != pi2.icon) return false; 4603 if (pi1.logo != pi2.logo) return false; 4604 if (pi1.protectionLevel != pi2.protectionLevel) return false; 4605 if (!compareStrings(pi1.name, pi2.name)) return false; 4606 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 4607 // We'll take care of setting this one. 4608 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 4609 // These are not currently stored in settings. 4610 //if (!compareStrings(pi1.group, pi2.group)) return false; 4611 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 4612 //if (pi1.labelRes != pi2.labelRes) return false; 4613 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 4614 return true; 4615 } 4616 4617 int permissionInfoFootprint(PermissionInfo info) { 4618 int size = info.name.length(); 4619 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 4620 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 4621 return size; 4622 } 4623 4624 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 4625 int size = 0; 4626 for (BasePermission perm : mSettings.mPermissions.values()) { 4627 if (perm.uid == tree.uid) { 4628 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 4629 } 4630 } 4631 return size; 4632 } 4633 4634 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 4635 // We calculate the max size of permissions defined by this uid and throw 4636 // if that plus the size of 'info' would exceed our stated maximum. 4637 if (tree.uid != Process.SYSTEM_UID) { 4638 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 4639 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 4640 throw new SecurityException("Permission tree size cap exceeded"); 4641 } 4642 } 4643 } 4644 4645 boolean addPermissionLocked(PermissionInfo info, boolean async) { 4646 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 4647 throw new SecurityException("Label must be specified in permission"); 4648 } 4649 BasePermission tree = checkPermissionTreeLP(info.name); 4650 BasePermission bp = mSettings.mPermissions.get(info.name); 4651 boolean added = bp == null; 4652 boolean changed = true; 4653 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 4654 if (added) { 4655 enforcePermissionCapLocked(info, tree); 4656 bp = new BasePermission(info.name, tree.sourcePackage, 4657 BasePermission.TYPE_DYNAMIC); 4658 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 4659 throw new SecurityException( 4660 "Not allowed to modify non-dynamic permission " 4661 + info.name); 4662 } else { 4663 if (bp.protectionLevel == fixedLevel 4664 && bp.perm.owner.equals(tree.perm.owner) 4665 && bp.uid == tree.uid 4666 && comparePermissionInfos(bp.perm.info, info)) { 4667 changed = false; 4668 } 4669 } 4670 bp.protectionLevel = fixedLevel; 4671 info = new PermissionInfo(info); 4672 info.protectionLevel = fixedLevel; 4673 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 4674 bp.perm.info.packageName = tree.perm.info.packageName; 4675 bp.uid = tree.uid; 4676 if (added) { 4677 mSettings.mPermissions.put(info.name, bp); 4678 } 4679 if (changed) { 4680 if (!async) { 4681 mSettings.writeLPr(); 4682 } else { 4683 scheduleWriteSettingsLocked(); 4684 } 4685 } 4686 return added; 4687 } 4688 4689 @Override 4690 public boolean addPermission(PermissionInfo info) { 4691 synchronized (mPackages) { 4692 return addPermissionLocked(info, false); 4693 } 4694 } 4695 4696 @Override 4697 public boolean addPermissionAsync(PermissionInfo info) { 4698 synchronized (mPackages) { 4699 return addPermissionLocked(info, true); 4700 } 4701 } 4702 4703 @Override 4704 public void removePermission(String name) { 4705 synchronized (mPackages) { 4706 checkPermissionTreeLP(name); 4707 BasePermission bp = mSettings.mPermissions.get(name); 4708 if (bp != null) { 4709 if (bp.type != BasePermission.TYPE_DYNAMIC) { 4710 throw new SecurityException( 4711 "Not allowed to modify non-dynamic permission " 4712 + name); 4713 } 4714 mSettings.mPermissions.remove(name); 4715 mSettings.writeLPr(); 4716 } 4717 } 4718 } 4719 4720 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 4721 BasePermission bp) { 4722 int index = pkg.requestedPermissions.indexOf(bp.name); 4723 if (index == -1) { 4724 throw new SecurityException("Package " + pkg.packageName 4725 + " has not requested permission " + bp.name); 4726 } 4727 if (!bp.isRuntime() && !bp.isDevelopment()) { 4728 throw new SecurityException("Permission " + bp.name 4729 + " is not a changeable permission type"); 4730 } 4731 } 4732 4733 @Override 4734 public void grantRuntimePermission(String packageName, String name, final int userId) { 4735 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4736 } 4737 4738 private void grantRuntimePermission(String packageName, String name, final int userId, 4739 boolean overridePolicy) { 4740 if (!sUserManager.exists(userId)) { 4741 Log.e(TAG, "No such user:" + userId); 4742 return; 4743 } 4744 4745 mContext.enforceCallingOrSelfPermission( 4746 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 4747 "grantRuntimePermission"); 4748 4749 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4750 true /* requireFullPermission */, true /* checkShell */, 4751 "grantRuntimePermission"); 4752 4753 final int uid; 4754 final SettingBase sb; 4755 4756 synchronized (mPackages) { 4757 final PackageParser.Package pkg = mPackages.get(packageName); 4758 if (pkg == null) { 4759 throw new IllegalArgumentException("Unknown package: " + packageName); 4760 } 4761 4762 final BasePermission bp = mSettings.mPermissions.get(name); 4763 if (bp == null) { 4764 throw new IllegalArgumentException("Unknown permission: " + name); 4765 } 4766 4767 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4768 4769 // If a permission review is required for legacy apps we represent 4770 // their permissions as always granted runtime ones since we need 4771 // to keep the review required permission flag per user while an 4772 // install permission's state is shared across all users. 4773 if (mPermissionReviewRequired 4774 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4775 && bp.isRuntime()) { 4776 return; 4777 } 4778 4779 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 4780 sb = (SettingBase) pkg.mExtras; 4781 if (sb == null) { 4782 throw new IllegalArgumentException("Unknown package: " + packageName); 4783 } 4784 4785 final PermissionsState permissionsState = sb.getPermissionsState(); 4786 4787 final int flags = permissionsState.getPermissionFlags(name, userId); 4788 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4789 throw new SecurityException("Cannot grant system fixed permission " 4790 + name + " for package " + packageName); 4791 } 4792 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4793 throw new SecurityException("Cannot grant policy fixed permission " 4794 + name + " for package " + packageName); 4795 } 4796 4797 if (bp.isDevelopment()) { 4798 // Development permissions must be handled specially, since they are not 4799 // normal runtime permissions. For now they apply to all users. 4800 if (permissionsState.grantInstallPermission(bp) != 4801 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4802 scheduleWriteSettingsLocked(); 4803 } 4804 return; 4805 } 4806 4807 final PackageSetting ps = mSettings.mPackages.get(packageName); 4808 if (ps.getInstantApp(userId) && !bp.isInstant()) { 4809 throw new SecurityException("Cannot grant non-ephemeral permission" 4810 + name + " for package " + packageName); 4811 } 4812 4813 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4814 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4815 return; 4816 } 4817 4818 final int result = permissionsState.grantRuntimePermission(bp, userId); 4819 switch (result) { 4820 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4821 return; 4822 } 4823 4824 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4825 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4826 mHandler.post(new Runnable() { 4827 @Override 4828 public void run() { 4829 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4830 } 4831 }); 4832 } 4833 break; 4834 } 4835 4836 if (bp.isRuntime()) { 4837 logPermissionGranted(mContext, name, packageName); 4838 } 4839 4840 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4841 4842 // Not critical if that is lost - app has to request again. 4843 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4844 } 4845 4846 // Only need to do this if user is initialized. Otherwise it's a new user 4847 // and there are no processes running as the user yet and there's no need 4848 // to make an expensive call to remount processes for the changed permissions. 4849 if (READ_EXTERNAL_STORAGE.equals(name) 4850 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4851 final long token = Binder.clearCallingIdentity(); 4852 try { 4853 if (sUserManager.isInitialized(userId)) { 4854 StorageManagerInternal storageManagerInternal = LocalServices.getService( 4855 StorageManagerInternal.class); 4856 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName); 4857 } 4858 } finally { 4859 Binder.restoreCallingIdentity(token); 4860 } 4861 } 4862 } 4863 4864 @Override 4865 public void revokeRuntimePermission(String packageName, String name, int userId) { 4866 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4867 } 4868 4869 private void revokeRuntimePermission(String packageName, String name, int userId, 4870 boolean overridePolicy) { 4871 if (!sUserManager.exists(userId)) { 4872 Log.e(TAG, "No such user:" + userId); 4873 return; 4874 } 4875 4876 mContext.enforceCallingOrSelfPermission( 4877 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4878 "revokeRuntimePermission"); 4879 4880 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4881 true /* requireFullPermission */, true /* checkShell */, 4882 "revokeRuntimePermission"); 4883 4884 final int appId; 4885 4886 synchronized (mPackages) { 4887 final PackageParser.Package pkg = mPackages.get(packageName); 4888 if (pkg == null) { 4889 throw new IllegalArgumentException("Unknown package: " + packageName); 4890 } 4891 4892 final BasePermission bp = mSettings.mPermissions.get(name); 4893 if (bp == null) { 4894 throw new IllegalArgumentException("Unknown permission: " + name); 4895 } 4896 4897 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4898 4899 // If a permission review is required for legacy apps we represent 4900 // their permissions as always granted runtime ones since we need 4901 // to keep the review required permission flag per user while an 4902 // install permission's state is shared across all users. 4903 if (mPermissionReviewRequired 4904 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4905 && bp.isRuntime()) { 4906 return; 4907 } 4908 4909 SettingBase sb = (SettingBase) pkg.mExtras; 4910 if (sb == null) { 4911 throw new IllegalArgumentException("Unknown package: " + packageName); 4912 } 4913 4914 final PermissionsState permissionsState = sb.getPermissionsState(); 4915 4916 final int flags = permissionsState.getPermissionFlags(name, userId); 4917 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4918 throw new SecurityException("Cannot revoke system fixed permission " 4919 + name + " for package " + packageName); 4920 } 4921 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4922 throw new SecurityException("Cannot revoke policy fixed permission " 4923 + name + " for package " + packageName); 4924 } 4925 4926 if (bp.isDevelopment()) { 4927 // Development permissions must be handled specially, since they are not 4928 // normal runtime permissions. For now they apply to all users. 4929 if (permissionsState.revokeInstallPermission(bp) != 4930 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4931 scheduleWriteSettingsLocked(); 4932 } 4933 return; 4934 } 4935 4936 if (permissionsState.revokeRuntimePermission(bp, userId) == 4937 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4938 return; 4939 } 4940 4941 if (bp.isRuntime()) { 4942 logPermissionRevoked(mContext, name, packageName); 4943 } 4944 4945 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4946 4947 // Critical, after this call app should never have the permission. 4948 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4949 4950 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4951 } 4952 4953 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4954 } 4955 4956 /** 4957 * Get the first event id for the permission. 4958 * 4959 * <p>There are four events for each permission: <ul> 4960 * <li>Request permission: first id + 0</li> 4961 * <li>Grant permission: first id + 1</li> 4962 * <li>Request for permission denied: first id + 2</li> 4963 * <li>Revoke permission: first id + 3</li> 4964 * </ul></p> 4965 * 4966 * @param name name of the permission 4967 * 4968 * @return The first event id for the permission 4969 */ 4970 private static int getBaseEventId(@NonNull String name) { 4971 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name); 4972 4973 if (eventIdIndex == -1) { 4974 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE 4975 || "user".equals(Build.TYPE)) { 4976 Log.i(TAG, "Unknown permission " + name); 4977 4978 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN; 4979 } else { 4980 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated. 4981 // 4982 // Also update 4983 // - EventLogger#ALL_DANGEROUS_PERMISSIONS 4984 // - metrics_constants.proto 4985 throw new IllegalStateException("Unknown permission " + name); 4986 } 4987 } 4988 4989 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4; 4990 } 4991 4992 /** 4993 * Log that a permission was revoked. 4994 * 4995 * @param context Context of the caller 4996 * @param name name of the permission 4997 * @param packageName package permission if for 4998 */ 4999 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name, 5000 @NonNull String packageName) { 5001 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName); 5002 } 5003 5004 /** 5005 * Log that a permission request was granted. 5006 * 5007 * @param context Context of the caller 5008 * @param name name of the permission 5009 * @param packageName package permission if for 5010 */ 5011 private static void logPermissionGranted(@NonNull Context context, @NonNull String name, 5012 @NonNull String packageName) { 5013 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName); 5014 } 5015 5016 @Override 5017 public void resetRuntimePermissions() { 5018 mContext.enforceCallingOrSelfPermission( 5019 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 5020 "revokeRuntimePermission"); 5021 5022 int callingUid = Binder.getCallingUid(); 5023 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 5024 mContext.enforceCallingOrSelfPermission( 5025 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5026 "resetRuntimePermissions"); 5027 } 5028 5029 synchronized (mPackages) { 5030 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 5031 for (int userId : UserManagerService.getInstance().getUserIds()) { 5032 final int packageCount = mPackages.size(); 5033 for (int i = 0; i < packageCount; i++) { 5034 PackageParser.Package pkg = mPackages.valueAt(i); 5035 if (!(pkg.mExtras instanceof PackageSetting)) { 5036 continue; 5037 } 5038 PackageSetting ps = (PackageSetting) pkg.mExtras; 5039 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 5040 } 5041 } 5042 } 5043 } 5044 5045 @Override 5046 public int getPermissionFlags(String name, String packageName, int userId) { 5047 if (!sUserManager.exists(userId)) { 5048 return 0; 5049 } 5050 5051 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 5052 5053 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5054 true /* requireFullPermission */, false /* checkShell */, 5055 "getPermissionFlags"); 5056 5057 synchronized (mPackages) { 5058 final PackageParser.Package pkg = mPackages.get(packageName); 5059 if (pkg == null) { 5060 return 0; 5061 } 5062 5063 final BasePermission bp = mSettings.mPermissions.get(name); 5064 if (bp == null) { 5065 return 0; 5066 } 5067 5068 SettingBase sb = (SettingBase) pkg.mExtras; 5069 if (sb == null) { 5070 return 0; 5071 } 5072 5073 PermissionsState permissionsState = sb.getPermissionsState(); 5074 return permissionsState.getPermissionFlags(name, userId); 5075 } 5076 } 5077 5078 @Override 5079 public void updatePermissionFlags(String name, String packageName, int flagMask, 5080 int flagValues, int userId) { 5081 if (!sUserManager.exists(userId)) { 5082 return; 5083 } 5084 5085 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 5086 5087 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5088 true /* requireFullPermission */, true /* checkShell */, 5089 "updatePermissionFlags"); 5090 5091 // Only the system can change these flags and nothing else. 5092 if (getCallingUid() != Process.SYSTEM_UID) { 5093 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5094 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5095 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 5096 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 5097 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 5098 } 5099 5100 synchronized (mPackages) { 5101 final PackageParser.Package pkg = mPackages.get(packageName); 5102 if (pkg == null) { 5103 throw new IllegalArgumentException("Unknown package: " + packageName); 5104 } 5105 5106 final BasePermission bp = mSettings.mPermissions.get(name); 5107 if (bp == null) { 5108 throw new IllegalArgumentException("Unknown permission: " + name); 5109 } 5110 5111 SettingBase sb = (SettingBase) pkg.mExtras; 5112 if (sb == null) { 5113 throw new IllegalArgumentException("Unknown package: " + packageName); 5114 } 5115 5116 PermissionsState permissionsState = sb.getPermissionsState(); 5117 5118 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 5119 5120 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 5121 // Install and runtime permissions are stored in different places, 5122 // so figure out what permission changed and persist the change. 5123 if (permissionsState.getInstallPermissionState(name) != null) { 5124 scheduleWriteSettingsLocked(); 5125 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 5126 || hadState) { 5127 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 5128 } 5129 } 5130 } 5131 } 5132 5133 /** 5134 * Update the permission flags for all packages and runtime permissions of a user in order 5135 * to allow device or profile owner to remove POLICY_FIXED. 5136 */ 5137 @Override 5138 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 5139 if (!sUserManager.exists(userId)) { 5140 return; 5141 } 5142 5143 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 5144 5145 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5146 true /* requireFullPermission */, true /* checkShell */, 5147 "updatePermissionFlagsForAllApps"); 5148 5149 // Only the system can change system fixed flags. 5150 if (getCallingUid() != Process.SYSTEM_UID) { 5151 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5152 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5153 } 5154 5155 synchronized (mPackages) { 5156 boolean changed = false; 5157 final int packageCount = mPackages.size(); 5158 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 5159 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 5160 SettingBase sb = (SettingBase) pkg.mExtras; 5161 if (sb == null) { 5162 continue; 5163 } 5164 PermissionsState permissionsState = sb.getPermissionsState(); 5165 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 5166 userId, flagMask, flagValues); 5167 } 5168 if (changed) { 5169 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 5170 } 5171 } 5172 } 5173 5174 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 5175 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 5176 != PackageManager.PERMISSION_GRANTED 5177 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 5178 != PackageManager.PERMISSION_GRANTED) { 5179 throw new SecurityException(message + " requires " 5180 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 5181 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 5182 } 5183 } 5184 5185 @Override 5186 public boolean shouldShowRequestPermissionRationale(String permissionName, 5187 String packageName, int userId) { 5188 if (UserHandle.getCallingUserId() != userId) { 5189 mContext.enforceCallingPermission( 5190 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5191 "canShowRequestPermissionRationale for user " + userId); 5192 } 5193 5194 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 5195 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 5196 return false; 5197 } 5198 5199 if (checkPermission(permissionName, packageName, userId) 5200 == PackageManager.PERMISSION_GRANTED) { 5201 return false; 5202 } 5203 5204 final int flags; 5205 5206 final long identity = Binder.clearCallingIdentity(); 5207 try { 5208 flags = getPermissionFlags(permissionName, 5209 packageName, userId); 5210 } finally { 5211 Binder.restoreCallingIdentity(identity); 5212 } 5213 5214 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 5215 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 5216 | PackageManager.FLAG_PERMISSION_USER_FIXED; 5217 5218 if ((flags & fixedFlags) != 0) { 5219 return false; 5220 } 5221 5222 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 5223 } 5224 5225 @Override 5226 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 5227 mContext.enforceCallingOrSelfPermission( 5228 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 5229 "addOnPermissionsChangeListener"); 5230 5231 synchronized (mPackages) { 5232 mOnPermissionChangeListeners.addListenerLocked(listener); 5233 } 5234 } 5235 5236 @Override 5237 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 5238 synchronized (mPackages) { 5239 mOnPermissionChangeListeners.removeListenerLocked(listener); 5240 } 5241 } 5242 5243 @Override 5244 public boolean isProtectedBroadcast(String actionName) { 5245 synchronized (mPackages) { 5246 if (mProtectedBroadcasts.contains(actionName)) { 5247 return true; 5248 } else if (actionName != null) { 5249 // TODO: remove these terrible hacks 5250 if (actionName.startsWith("android.net.netmon.lingerExpired") 5251 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 5252 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 5253 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 5254 return true; 5255 } 5256 } 5257 } 5258 return false; 5259 } 5260 5261 @Override 5262 public int checkSignatures(String pkg1, String pkg2) { 5263 synchronized (mPackages) { 5264 final PackageParser.Package p1 = mPackages.get(pkg1); 5265 final PackageParser.Package p2 = mPackages.get(pkg2); 5266 if (p1 == null || p1.mExtras == null 5267 || p2 == null || p2.mExtras == null) { 5268 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5269 } 5270 return compareSignatures(p1.mSignatures, p2.mSignatures); 5271 } 5272 } 5273 5274 @Override 5275 public int checkUidSignatures(int uid1, int uid2) { 5276 // Map to base uids. 5277 uid1 = UserHandle.getAppId(uid1); 5278 uid2 = UserHandle.getAppId(uid2); 5279 // reader 5280 synchronized (mPackages) { 5281 Signature[] s1; 5282 Signature[] s2; 5283 Object obj = mSettings.getUserIdLPr(uid1); 5284 if (obj != null) { 5285 if (obj instanceof SharedUserSetting) { 5286 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 5287 } else if (obj instanceof PackageSetting) { 5288 s1 = ((PackageSetting)obj).signatures.mSignatures; 5289 } else { 5290 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5291 } 5292 } else { 5293 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5294 } 5295 obj = mSettings.getUserIdLPr(uid2); 5296 if (obj != null) { 5297 if (obj instanceof SharedUserSetting) { 5298 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 5299 } else if (obj instanceof PackageSetting) { 5300 s2 = ((PackageSetting)obj).signatures.mSignatures; 5301 } else { 5302 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5303 } 5304 } else { 5305 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5306 } 5307 return compareSignatures(s1, s2); 5308 } 5309 } 5310 5311 /** 5312 * This method should typically only be used when granting or revoking 5313 * permissions, since the app may immediately restart after this call. 5314 * <p> 5315 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 5316 * guard your work against the app being relaunched. 5317 */ 5318 private void killUid(int appId, int userId, String reason) { 5319 final long identity = Binder.clearCallingIdentity(); 5320 try { 5321 IActivityManager am = ActivityManager.getService(); 5322 if (am != null) { 5323 try { 5324 am.killUid(appId, userId, reason); 5325 } catch (RemoteException e) { 5326 /* ignore - same process */ 5327 } 5328 } 5329 } finally { 5330 Binder.restoreCallingIdentity(identity); 5331 } 5332 } 5333 5334 /** 5335 * Compares two sets of signatures. Returns: 5336 * <br /> 5337 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 5338 * <br /> 5339 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 5340 * <br /> 5341 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 5342 * <br /> 5343 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 5344 * <br /> 5345 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 5346 */ 5347 static int compareSignatures(Signature[] s1, Signature[] s2) { 5348 if (s1 == null) { 5349 return s2 == null 5350 ? PackageManager.SIGNATURE_NEITHER_SIGNED 5351 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 5352 } 5353 5354 if (s2 == null) { 5355 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 5356 } 5357 5358 if (s1.length != s2.length) { 5359 return PackageManager.SIGNATURE_NO_MATCH; 5360 } 5361 5362 // Since both signature sets are of size 1, we can compare without HashSets. 5363 if (s1.length == 1) { 5364 return s1[0].equals(s2[0]) ? 5365 PackageManager.SIGNATURE_MATCH : 5366 PackageManager.SIGNATURE_NO_MATCH; 5367 } 5368 5369 ArraySet<Signature> set1 = new ArraySet<Signature>(); 5370 for (Signature sig : s1) { 5371 set1.add(sig); 5372 } 5373 ArraySet<Signature> set2 = new ArraySet<Signature>(); 5374 for (Signature sig : s2) { 5375 set2.add(sig); 5376 } 5377 // Make sure s2 contains all signatures in s1. 5378 if (set1.equals(set2)) { 5379 return PackageManager.SIGNATURE_MATCH; 5380 } 5381 return PackageManager.SIGNATURE_NO_MATCH; 5382 } 5383 5384 /** 5385 * If the database version for this type of package (internal storage or 5386 * external storage) is less than the version where package signatures 5387 * were updated, return true. 5388 */ 5389 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 5390 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 5391 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 5392 } 5393 5394 /** 5395 * Used for backward compatibility to make sure any packages with 5396 * certificate chains get upgraded to the new style. {@code existingSigs} 5397 * will be in the old format (since they were stored on disk from before the 5398 * system upgrade) and {@code scannedSigs} will be in the newer format. 5399 */ 5400 private int compareSignaturesCompat(PackageSignatures existingSigs, 5401 PackageParser.Package scannedPkg) { 5402 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 5403 return PackageManager.SIGNATURE_NO_MATCH; 5404 } 5405 5406 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 5407 for (Signature sig : existingSigs.mSignatures) { 5408 existingSet.add(sig); 5409 } 5410 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 5411 for (Signature sig : scannedPkg.mSignatures) { 5412 try { 5413 Signature[] chainSignatures = sig.getChainSignatures(); 5414 for (Signature chainSig : chainSignatures) { 5415 scannedCompatSet.add(chainSig); 5416 } 5417 } catch (CertificateEncodingException e) { 5418 scannedCompatSet.add(sig); 5419 } 5420 } 5421 /* 5422 * Make sure the expanded scanned set contains all signatures in the 5423 * existing one. 5424 */ 5425 if (scannedCompatSet.equals(existingSet)) { 5426 // Migrate the old signatures to the new scheme. 5427 existingSigs.assignSignatures(scannedPkg.mSignatures); 5428 // The new KeySets will be re-added later in the scanning process. 5429 synchronized (mPackages) { 5430 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 5431 } 5432 return PackageManager.SIGNATURE_MATCH; 5433 } 5434 return PackageManager.SIGNATURE_NO_MATCH; 5435 } 5436 5437 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 5438 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 5439 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 5440 } 5441 5442 private int compareSignaturesRecover(PackageSignatures existingSigs, 5443 PackageParser.Package scannedPkg) { 5444 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 5445 return PackageManager.SIGNATURE_NO_MATCH; 5446 } 5447 5448 String msg = null; 5449 try { 5450 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 5451 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 5452 + scannedPkg.packageName); 5453 return PackageManager.SIGNATURE_MATCH; 5454 } 5455 } catch (CertificateException e) { 5456 msg = e.getMessage(); 5457 } 5458 5459 logCriticalInfo(Log.INFO, 5460 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 5461 return PackageManager.SIGNATURE_NO_MATCH; 5462 } 5463 5464 @Override 5465 public List<String> getAllPackages() { 5466 synchronized (mPackages) { 5467 return new ArrayList<String>(mPackages.keySet()); 5468 } 5469 } 5470 5471 @Override 5472 public String[] getPackagesForUid(int uid) { 5473 final int userId = UserHandle.getUserId(uid); 5474 uid = UserHandle.getAppId(uid); 5475 // reader 5476 synchronized (mPackages) { 5477 Object obj = mSettings.getUserIdLPr(uid); 5478 if (obj instanceof SharedUserSetting) { 5479 final SharedUserSetting sus = (SharedUserSetting) obj; 5480 final int N = sus.packages.size(); 5481 String[] res = new String[N]; 5482 final Iterator<PackageSetting> it = sus.packages.iterator(); 5483 int i = 0; 5484 while (it.hasNext()) { 5485 PackageSetting ps = it.next(); 5486 if (ps.getInstalled(userId)) { 5487 res[i++] = ps.name; 5488 } else { 5489 res = ArrayUtils.removeElement(String.class, res, res[i]); 5490 } 5491 } 5492 return res; 5493 } else if (obj instanceof PackageSetting) { 5494 final PackageSetting ps = (PackageSetting) obj; 5495 if (ps.getInstalled(userId)) { 5496 return new String[]{ps.name}; 5497 } 5498 } 5499 } 5500 return null; 5501 } 5502 5503 @Override 5504 public String getNameForUid(int uid) { 5505 // reader 5506 synchronized (mPackages) { 5507 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5508 if (obj instanceof SharedUserSetting) { 5509 final SharedUserSetting sus = (SharedUserSetting) obj; 5510 return sus.name + ":" + sus.userId; 5511 } else if (obj instanceof PackageSetting) { 5512 final PackageSetting ps = (PackageSetting) obj; 5513 return ps.name; 5514 } 5515 } 5516 return null; 5517 } 5518 5519 @Override 5520 public int getUidForSharedUser(String sharedUserName) { 5521 if(sharedUserName == null) { 5522 return -1; 5523 } 5524 // reader 5525 synchronized (mPackages) { 5526 SharedUserSetting suid; 5527 try { 5528 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 5529 if (suid != null) { 5530 return suid.userId; 5531 } 5532 } catch (PackageManagerException ignore) { 5533 // can't happen, but, still need to catch it 5534 } 5535 return -1; 5536 } 5537 } 5538 5539 @Override 5540 public int getFlagsForUid(int uid) { 5541 synchronized (mPackages) { 5542 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5543 if (obj instanceof SharedUserSetting) { 5544 final SharedUserSetting sus = (SharedUserSetting) obj; 5545 return sus.pkgFlags; 5546 } else if (obj instanceof PackageSetting) { 5547 final PackageSetting ps = (PackageSetting) obj; 5548 return ps.pkgFlags; 5549 } 5550 } 5551 return 0; 5552 } 5553 5554 @Override 5555 public int getPrivateFlagsForUid(int uid) { 5556 synchronized (mPackages) { 5557 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5558 if (obj instanceof SharedUserSetting) { 5559 final SharedUserSetting sus = (SharedUserSetting) obj; 5560 return sus.pkgPrivateFlags; 5561 } else if (obj instanceof PackageSetting) { 5562 final PackageSetting ps = (PackageSetting) obj; 5563 return ps.pkgPrivateFlags; 5564 } 5565 } 5566 return 0; 5567 } 5568 5569 @Override 5570 public boolean isUidPrivileged(int uid) { 5571 uid = UserHandle.getAppId(uid); 5572 // reader 5573 synchronized (mPackages) { 5574 Object obj = mSettings.getUserIdLPr(uid); 5575 if (obj instanceof SharedUserSetting) { 5576 final SharedUserSetting sus = (SharedUserSetting) obj; 5577 final Iterator<PackageSetting> it = sus.packages.iterator(); 5578 while (it.hasNext()) { 5579 if (it.next().isPrivileged()) { 5580 return true; 5581 } 5582 } 5583 } else if (obj instanceof PackageSetting) { 5584 final PackageSetting ps = (PackageSetting) obj; 5585 return ps.isPrivileged(); 5586 } 5587 } 5588 return false; 5589 } 5590 5591 @Override 5592 public String[] getAppOpPermissionPackages(String permissionName) { 5593 synchronized (mPackages) { 5594 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 5595 if (pkgs == null) { 5596 return null; 5597 } 5598 return pkgs.toArray(new String[pkgs.size()]); 5599 } 5600 } 5601 5602 @Override 5603 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 5604 int flags, int userId) { 5605 return resolveIntentInternal( 5606 intent, resolvedType, flags, userId, false /*includeInstantApp*/); 5607 } 5608 5609 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, 5610 int flags, int userId, boolean includeInstantApp) { 5611 try { 5612 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 5613 5614 if (!sUserManager.exists(userId)) return null; 5615 flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp); 5616 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5617 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 5618 5619 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5620 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 5621 flags, userId, includeInstantApp); 5622 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5623 5624 final ResolveInfo bestChoice = 5625 chooseBestActivity(intent, resolvedType, flags, query, userId); 5626 return bestChoice; 5627 } finally { 5628 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5629 } 5630 } 5631 5632 @Override 5633 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) { 5634 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) { 5635 throw new SecurityException( 5636 "findPersistentPreferredActivity can only be run by the system"); 5637 } 5638 if (!sUserManager.exists(userId)) { 5639 return null; 5640 } 5641 intent = updateIntentForResolve(intent); 5642 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver()); 5643 final int flags = updateFlagsForResolve(0, userId, intent, false); 5644 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5645 userId); 5646 synchronized (mPackages) { 5647 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false, 5648 userId); 5649 } 5650 } 5651 5652 @Override 5653 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 5654 IntentFilter filter, int match, ComponentName activity) { 5655 final int userId = UserHandle.getCallingUserId(); 5656 if (DEBUG_PREFERRED) { 5657 Log.v(TAG, "setLastChosenActivity intent=" + intent 5658 + " resolvedType=" + resolvedType 5659 + " flags=" + flags 5660 + " filter=" + filter 5661 + " match=" + match 5662 + " activity=" + activity); 5663 filter.dump(new PrintStreamPrinter(System.out), " "); 5664 } 5665 intent.setComponent(null); 5666 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5667 userId); 5668 // Find any earlier preferred or last chosen entries and nuke them 5669 findPreferredActivity(intent, resolvedType, 5670 flags, query, 0, false, true, false, userId); 5671 // Add the new activity as the last chosen for this filter 5672 addPreferredActivityInternal(filter, match, null, activity, false, userId, 5673 "Setting last chosen"); 5674 } 5675 5676 @Override 5677 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 5678 final int userId = UserHandle.getCallingUserId(); 5679 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 5680 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5681 userId); 5682 return findPreferredActivity(intent, resolvedType, flags, query, 0, 5683 false, false, false, userId); 5684 } 5685 5686 /** 5687 * Returns whether or not instant apps have been disabled remotely. 5688 * <p><em>IMPORTANT</em> This should not be called with the package manager lock 5689 * held. Otherwise we run the risk of deadlock. 5690 */ 5691 private boolean isEphemeralDisabled() { 5692 // ephemeral apps have been disabled across the board 5693 if (DISABLE_EPHEMERAL_APPS) { 5694 return true; 5695 } 5696 // system isn't up yet; can't read settings, so, assume no ephemeral apps 5697 if (!mSystemReady) { 5698 return true; 5699 } 5700 // we can't get a content resolver until the system is ready; these checks must happen last 5701 final ContentResolver resolver = mContext.getContentResolver(); 5702 if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) { 5703 return true; 5704 } 5705 return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0; 5706 } 5707 5708 private boolean isEphemeralAllowed( 5709 Intent intent, List<ResolveInfo> resolvedActivities, int userId, 5710 boolean skipPackageCheck) { 5711 final int callingUser = UserHandle.getCallingUserId(); 5712 if (callingUser != UserHandle.USER_SYSTEM) { 5713 return false; 5714 } 5715 if (mInstantAppResolverConnection == null) { 5716 return false; 5717 } 5718 if (mInstantAppInstallerComponent == null) { 5719 return false; 5720 } 5721 if (intent.getComponent() != null) { 5722 return false; 5723 } 5724 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) { 5725 return false; 5726 } 5727 if (!skipPackageCheck && intent.getPackage() != null) { 5728 return false; 5729 } 5730 final boolean isWebUri = hasWebURI(intent); 5731 if (!isWebUri || intent.getData().getHost() == null) { 5732 return false; 5733 } 5734 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 5735 // Or if there's already an ephemeral app installed that handles the action 5736 synchronized (mPackages) { 5737 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); 5738 for (int n = 0; n < count; n++) { 5739 ResolveInfo info = resolvedActivities.get(n); 5740 String packageName = info.activityInfo.packageName; 5741 PackageSetting ps = mSettings.mPackages.get(packageName); 5742 if (ps != null) { 5743 // Try to get the status from User settings first 5744 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5745 int status = (int) (packedStatus >> 32); 5746 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 5747 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5748 if (DEBUG_EPHEMERAL) { 5749 Slog.v(TAG, "DENY ephemeral apps;" 5750 + " pkg: " + packageName + ", status: " + status); 5751 } 5752 return false; 5753 } 5754 if (ps.getInstantApp(userId)) { 5755 return false; 5756 } 5757 } 5758 } 5759 } 5760 // We've exhausted all ways to deny ephemeral application; let the system look for them. 5761 return true; 5762 } 5763 5764 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, 5765 Intent origIntent, String resolvedType, String callingPackage, 5766 int userId) { 5767 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO, 5768 new InstantAppRequest(responseObj, origIntent, resolvedType, 5769 callingPackage, userId)); 5770 mHandler.sendMessage(msg); 5771 } 5772 5773 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 5774 int flags, List<ResolveInfo> query, int userId) { 5775 if (query != null) { 5776 final int N = query.size(); 5777 if (N == 1) { 5778 return query.get(0); 5779 } else if (N > 1) { 5780 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 5781 // If there is more than one activity with the same priority, 5782 // then let the user decide between them. 5783 ResolveInfo r0 = query.get(0); 5784 ResolveInfo r1 = query.get(1); 5785 if (DEBUG_INTENT_MATCHING || debug) { 5786 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 5787 + r1.activityInfo.name + "=" + r1.priority); 5788 } 5789 // If the first activity has a higher priority, or a different 5790 // default, then it is always desirable to pick it. 5791 if (r0.priority != r1.priority 5792 || r0.preferredOrder != r1.preferredOrder 5793 || r0.isDefault != r1.isDefault) { 5794 return query.get(0); 5795 } 5796 // If we have saved a preference for a preferred activity for 5797 // this Intent, use that. 5798 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 5799 flags, query, r0.priority, true, false, debug, userId); 5800 if (ri != null) { 5801 return ri; 5802 } 5803 // If we have an ephemeral app, use it 5804 for (int i = 0; i < N; i++) { 5805 ri = query.get(i); 5806 if (ri.activityInfo.applicationInfo.isInstantApp()) { 5807 return ri; 5808 } 5809 } 5810 ri = new ResolveInfo(mResolveInfo); 5811 ri.activityInfo = new ActivityInfo(ri.activityInfo); 5812 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 5813 // If all of the options come from the same package, show the application's 5814 // label and icon instead of the generic resolver's. 5815 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 5816 // and then throw away the ResolveInfo itself, meaning that the caller loses 5817 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 5818 // a fallback for this case; we only set the target package's resources on 5819 // the ResolveInfo, not the ActivityInfo. 5820 final String intentPackage = intent.getPackage(); 5821 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 5822 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 5823 ri.resolvePackageName = intentPackage; 5824 if (userNeedsBadging(userId)) { 5825 ri.noResourceId = true; 5826 } else { 5827 ri.icon = appi.icon; 5828 } 5829 ri.iconResourceId = appi.icon; 5830 ri.labelRes = appi.labelRes; 5831 } 5832 ri.activityInfo.applicationInfo = new ApplicationInfo( 5833 ri.activityInfo.applicationInfo); 5834 if (userId != 0) { 5835 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 5836 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 5837 } 5838 // Make sure that the resolver is displayable in car mode 5839 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 5840 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 5841 return ri; 5842 } 5843 } 5844 return null; 5845 } 5846 5847 /** 5848 * Return true if the given list is not empty and all of its contents have 5849 * an activityInfo with the given package name. 5850 */ 5851 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 5852 if (ArrayUtils.isEmpty(list)) { 5853 return false; 5854 } 5855 for (int i = 0, N = list.size(); i < N; i++) { 5856 final ResolveInfo ri = list.get(i); 5857 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 5858 if (ai == null || !packageName.equals(ai.packageName)) { 5859 return false; 5860 } 5861 } 5862 return true; 5863 } 5864 5865 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 5866 int flags, List<ResolveInfo> query, boolean debug, int userId) { 5867 final int N = query.size(); 5868 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 5869 .get(userId); 5870 // Get the list of persistent preferred activities that handle the intent 5871 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 5872 List<PersistentPreferredActivity> pprefs = ppir != null 5873 ? ppir.queryIntent(intent, resolvedType, 5874 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5875 userId) 5876 : null; 5877 if (pprefs != null && pprefs.size() > 0) { 5878 final int M = pprefs.size(); 5879 for (int i=0; i<M; i++) { 5880 final PersistentPreferredActivity ppa = pprefs.get(i); 5881 if (DEBUG_PREFERRED || debug) { 5882 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 5883 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 5884 + "\n component=" + ppa.mComponent); 5885 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5886 } 5887 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 5888 flags | MATCH_DISABLED_COMPONENTS, userId); 5889 if (DEBUG_PREFERRED || debug) { 5890 Slog.v(TAG, "Found persistent preferred activity:"); 5891 if (ai != null) { 5892 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5893 } else { 5894 Slog.v(TAG, " null"); 5895 } 5896 } 5897 if (ai == null) { 5898 // This previously registered persistent preferred activity 5899 // component is no longer known. Ignore it and do NOT remove it. 5900 continue; 5901 } 5902 for (int j=0; j<N; j++) { 5903 final ResolveInfo ri = query.get(j); 5904 if (!ri.activityInfo.applicationInfo.packageName 5905 .equals(ai.applicationInfo.packageName)) { 5906 continue; 5907 } 5908 if (!ri.activityInfo.name.equals(ai.name)) { 5909 continue; 5910 } 5911 // Found a persistent preference that can handle the intent. 5912 if (DEBUG_PREFERRED || debug) { 5913 Slog.v(TAG, "Returning persistent preferred activity: " + 5914 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5915 } 5916 return ri; 5917 } 5918 } 5919 } 5920 return null; 5921 } 5922 5923 // TODO: handle preferred activities missing while user has amnesia 5924 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5925 List<ResolveInfo> query, int priority, boolean always, 5926 boolean removeMatches, boolean debug, int userId) { 5927 if (!sUserManager.exists(userId)) return null; 5928 flags = updateFlagsForResolve(flags, userId, intent, false); 5929 intent = updateIntentForResolve(intent); 5930 // writer 5931 synchronized (mPackages) { 5932 // Try to find a matching persistent preferred activity. 5933 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5934 debug, userId); 5935 5936 // If a persistent preferred activity matched, use it. 5937 if (pri != null) { 5938 return pri; 5939 } 5940 5941 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5942 // Get the list of preferred activities that handle the intent 5943 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5944 List<PreferredActivity> prefs = pir != null 5945 ? pir.queryIntent(intent, resolvedType, 5946 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5947 userId) 5948 : null; 5949 if (prefs != null && prefs.size() > 0) { 5950 boolean changed = false; 5951 try { 5952 // First figure out how good the original match set is. 5953 // We will only allow preferred activities that came 5954 // from the same match quality. 5955 int match = 0; 5956 5957 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5958 5959 final int N = query.size(); 5960 for (int j=0; j<N; j++) { 5961 final ResolveInfo ri = query.get(j); 5962 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 5963 + ": 0x" + Integer.toHexString(match)); 5964 if (ri.match > match) { 5965 match = ri.match; 5966 } 5967 } 5968 5969 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 5970 + Integer.toHexString(match)); 5971 5972 match &= IntentFilter.MATCH_CATEGORY_MASK; 5973 final int M = prefs.size(); 5974 for (int i=0; i<M; i++) { 5975 final PreferredActivity pa = prefs.get(i); 5976 if (DEBUG_PREFERRED || debug) { 5977 Slog.v(TAG, "Checking PreferredActivity ds=" 5978 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5979 + "\n component=" + pa.mPref.mComponent); 5980 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5981 } 5982 if (pa.mPref.mMatch != match) { 5983 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5984 + Integer.toHexString(pa.mPref.mMatch)); 5985 continue; 5986 } 5987 // If it's not an "always" type preferred activity and that's what we're 5988 // looking for, skip it. 5989 if (always && !pa.mPref.mAlways) { 5990 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5991 continue; 5992 } 5993 final ActivityInfo ai = getActivityInfo( 5994 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5995 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5996 userId); 5997 if (DEBUG_PREFERRED || debug) { 5998 Slog.v(TAG, "Found preferred activity:"); 5999 if (ai != null) { 6000 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 6001 } else { 6002 Slog.v(TAG, " null"); 6003 } 6004 } 6005 if (ai == null) { 6006 // This previously registered preferred activity 6007 // component is no longer known. Most likely an update 6008 // to the app was installed and in the new version this 6009 // component no longer exists. Clean it up by removing 6010 // it from the preferred activities list, and skip it. 6011 Slog.w(TAG, "Removing dangling preferred activity: " 6012 + pa.mPref.mComponent); 6013 pir.removeFilter(pa); 6014 changed = true; 6015 continue; 6016 } 6017 for (int j=0; j<N; j++) { 6018 final ResolveInfo ri = query.get(j); 6019 if (!ri.activityInfo.applicationInfo.packageName 6020 .equals(ai.applicationInfo.packageName)) { 6021 continue; 6022 } 6023 if (!ri.activityInfo.name.equals(ai.name)) { 6024 continue; 6025 } 6026 6027 if (removeMatches) { 6028 pir.removeFilter(pa); 6029 changed = true; 6030 if (DEBUG_PREFERRED) { 6031 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 6032 } 6033 break; 6034 } 6035 6036 // Okay we found a previously set preferred or last chosen app. 6037 // If the result set is different from when this 6038 // was created, we need to clear it and re-ask the 6039 // user their preference, if we're looking for an "always" type entry. 6040 if (always && !pa.mPref.sameSet(query)) { 6041 Slog.i(TAG, "Result set changed, dropping preferred activity for " 6042 + intent + " type " + resolvedType); 6043 if (DEBUG_PREFERRED) { 6044 Slog.v(TAG, "Removing preferred activity since set changed " 6045 + pa.mPref.mComponent); 6046 } 6047 pir.removeFilter(pa); 6048 // Re-add the filter as a "last chosen" entry (!always) 6049 PreferredActivity lastChosen = new PreferredActivity( 6050 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 6051 pir.addFilter(lastChosen); 6052 changed = true; 6053 return null; 6054 } 6055 6056 // Yay! Either the set matched or we're looking for the last chosen 6057 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 6058 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 6059 return ri; 6060 } 6061 } 6062 } finally { 6063 if (changed) { 6064 if (DEBUG_PREFERRED) { 6065 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 6066 } 6067 scheduleWritePackageRestrictionsLocked(userId); 6068 } 6069 } 6070 } 6071 } 6072 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 6073 return null; 6074 } 6075 6076 /* 6077 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 6078 */ 6079 @Override 6080 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 6081 int targetUserId) { 6082 mContext.enforceCallingOrSelfPermission( 6083 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 6084 List<CrossProfileIntentFilter> matches = 6085 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 6086 if (matches != null) { 6087 int size = matches.size(); 6088 for (int i = 0; i < size; i++) { 6089 if (matches.get(i).getTargetUserId() == targetUserId) return true; 6090 } 6091 } 6092 if (hasWebURI(intent)) { 6093 // cross-profile app linking works only towards the parent. 6094 final UserInfo parent = getProfileParent(sourceUserId); 6095 synchronized(mPackages) { 6096 int flags = updateFlagsForResolve(0, parent.id, intent, false); 6097 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 6098 intent, resolvedType, flags, sourceUserId, parent.id); 6099 return xpDomainInfo != null; 6100 } 6101 } 6102 return false; 6103 } 6104 6105 private UserInfo getProfileParent(int userId) { 6106 final long identity = Binder.clearCallingIdentity(); 6107 try { 6108 return sUserManager.getProfileParent(userId); 6109 } finally { 6110 Binder.restoreCallingIdentity(identity); 6111 } 6112 } 6113 6114 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 6115 String resolvedType, int userId) { 6116 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 6117 if (resolver != null) { 6118 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId); 6119 } 6120 return null; 6121 } 6122 6123 @Override 6124 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 6125 String resolvedType, int flags, int userId) { 6126 try { 6127 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 6128 6129 return new ParceledListSlice<>( 6130 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 6131 } finally { 6132 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6133 } 6134 } 6135 6136 /** 6137 * Returns the package name of the calling Uid if it's an instant app. If it isn't 6138 * instant, returns {@code null}. 6139 */ 6140 private String getInstantAppPackageName(int callingUid) { 6141 final int appId = UserHandle.getAppId(callingUid); 6142 synchronized (mPackages) { 6143 final Object obj = mSettings.getUserIdLPr(appId); 6144 if (obj instanceof PackageSetting) { 6145 final PackageSetting ps = (PackageSetting) obj; 6146 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid)); 6147 return isInstantApp ? ps.pkg.packageName : null; 6148 } 6149 } 6150 return null; 6151 } 6152 6153 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 6154 String resolvedType, int flags, int userId) { 6155 return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false); 6156 } 6157 6158 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 6159 String resolvedType, int flags, int userId, boolean includeInstantApp) { 6160 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6161 final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid()); 6162 flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp); 6163 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6164 false /* requireFullPermission */, false /* checkShell */, 6165 "query intent activities"); 6166 ComponentName comp = intent.getComponent(); 6167 if (comp == null) { 6168 if (intent.getSelector() != null) { 6169 intent = intent.getSelector(); 6170 comp = intent.getComponent(); 6171 } 6172 } 6173 6174 if (comp != null) { 6175 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6176 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 6177 if (ai != null) { 6178 // When specifying an explicit component, we prevent the activity from being 6179 // used when either 1) the calling package is normal and the activity is within 6180 // an ephemeral application or 2) the calling package is ephemeral and the 6181 // activity is not visible to ephemeral applications. 6182 final boolean matchInstantApp = 6183 (flags & PackageManager.MATCH_INSTANT) != 0; 6184 final boolean matchVisibleToInstantAppOnly = 6185 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; 6186 final boolean isCallerInstantApp = 6187 instantAppPkgName != null; 6188 final boolean isTargetSameInstantApp = 6189 comp.getPackageName().equals(instantAppPkgName); 6190 final boolean isTargetInstantApp = 6191 (ai.applicationInfo.privateFlags 6192 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0; 6193 final boolean isTargetHiddenFromInstantApp = 6194 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0; 6195 final boolean blockResolution = 6196 !isTargetSameInstantApp 6197 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp) 6198 || (matchVisibleToInstantAppOnly && isCallerInstantApp 6199 && isTargetHiddenFromInstantApp)); 6200 if (!blockResolution) { 6201 final ResolveInfo ri = new ResolveInfo(); 6202 ri.activityInfo = ai; 6203 list.add(ri); 6204 } 6205 } 6206 return applyPostResolutionFilter(list, instantAppPkgName); 6207 } 6208 6209 // reader 6210 boolean sortResult = false; 6211 boolean addEphemeral = false; 6212 List<ResolveInfo> result; 6213 final String pkgName = intent.getPackage(); 6214 final boolean ephemeralDisabled = isEphemeralDisabled(); 6215 synchronized (mPackages) { 6216 if (pkgName == null) { 6217 List<CrossProfileIntentFilter> matchingFilters = 6218 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 6219 // Check for results that need to skip the current profile. 6220 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 6221 resolvedType, flags, userId); 6222 if (xpResolveInfo != null) { 6223 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); 6224 xpResult.add(xpResolveInfo); 6225 return applyPostResolutionFilter( 6226 filterIfNotSystemUser(xpResult, userId), instantAppPkgName); 6227 } 6228 6229 // Check for results in the current profile. 6230 result = filterIfNotSystemUser(mActivities.queryIntent( 6231 intent, resolvedType, flags, userId), userId); 6232 addEphemeral = !ephemeralDisabled 6233 && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); 6234 6235 // Check for cross profile results. 6236 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 6237 xpResolveInfo = queryCrossProfileIntents( 6238 matchingFilters, intent, resolvedType, flags, userId, 6239 hasNonNegativePriorityResult); 6240 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 6241 boolean isVisibleToUser = filterIfNotSystemUser( 6242 Collections.singletonList(xpResolveInfo), userId).size() > 0; 6243 if (isVisibleToUser) { 6244 result.add(xpResolveInfo); 6245 sortResult = true; 6246 } 6247 } 6248 if (hasWebURI(intent)) { 6249 CrossProfileDomainInfo xpDomainInfo = null; 6250 final UserInfo parent = getProfileParent(userId); 6251 if (parent != null) { 6252 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 6253 flags, userId, parent.id); 6254 } 6255 if (xpDomainInfo != null) { 6256 if (xpResolveInfo != null) { 6257 // If we didn't remove it, the cross-profile ResolveInfo would be twice 6258 // in the result. 6259 result.remove(xpResolveInfo); 6260 } 6261 if (result.size() == 0 && !addEphemeral) { 6262 // No result in current profile, but found candidate in parent user. 6263 // And we are not going to add emphemeral app, so we can return the 6264 // result straight away. 6265 result.add(xpDomainInfo.resolveInfo); 6266 return applyPostResolutionFilter(result, instantAppPkgName); 6267 } 6268 } else if (result.size() <= 1 && !addEphemeral) { 6269 // No result in parent user and <= 1 result in current profile, and we 6270 // are not going to add emphemeral app, so we can return the result without 6271 // further processing. 6272 return applyPostResolutionFilter(result, instantAppPkgName); 6273 } 6274 // We have more than one candidate (combining results from current and parent 6275 // profile), so we need filtering and sorting. 6276 result = filterCandidatesWithDomainPreferredActivitiesLPr( 6277 intent, flags, result, xpDomainInfo, userId); 6278 sortResult = true; 6279 } 6280 } else { 6281 final PackageParser.Package pkg = mPackages.get(pkgName); 6282 if (pkg != null) { 6283 result = applyPostResolutionFilter(filterIfNotSystemUser( 6284 mActivities.queryIntentForPackage( 6285 intent, resolvedType, flags, pkg.activities, userId), 6286 userId), instantAppPkgName); 6287 } else { 6288 // the caller wants to resolve for a particular package; however, there 6289 // were no installed results, so, try to find an ephemeral result 6290 addEphemeral = !ephemeralDisabled 6291 && isEphemeralAllowed( 6292 intent, null /*result*/, userId, true /*skipPackageCheck*/); 6293 result = new ArrayList<ResolveInfo>(); 6294 } 6295 } 6296 } 6297 if (addEphemeral) { 6298 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 6299 final InstantAppRequest requestObject = new InstantAppRequest( 6300 null /*responseObj*/, intent /*origIntent*/, resolvedType, 6301 null /*callingPackage*/, userId); 6302 final AuxiliaryResolveInfo auxiliaryResponse = 6303 InstantAppResolver.doInstantAppResolutionPhaseOne( 6304 mContext, mInstantAppResolverConnection, requestObject); 6305 if (auxiliaryResponse != null) { 6306 if (DEBUG_EPHEMERAL) { 6307 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 6308 } 6309 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo); 6310 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse; 6311 // make sure this resolver is the default 6312 ephemeralInstaller.isDefault = true; 6313 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 6314 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 6315 // add a non-generic filter 6316 ephemeralInstaller.filter = new IntentFilter(intent.getAction()); 6317 ephemeralInstaller.filter.addDataPath( 6318 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL); 6319 ephemeralInstaller.instantAppAvailable = true; 6320 result.add(ephemeralInstaller); 6321 } 6322 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6323 } 6324 if (sortResult) { 6325 Collections.sort(result, mResolvePrioritySorter); 6326 } 6327 return applyPostResolutionFilter(result, instantAppPkgName); 6328 } 6329 6330 private static class CrossProfileDomainInfo { 6331 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 6332 ResolveInfo resolveInfo; 6333 /* Best domain verification status of the activities found in the other profile */ 6334 int bestDomainVerificationStatus; 6335 } 6336 6337 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 6338 String resolvedType, int flags, int sourceUserId, int parentUserId) { 6339 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 6340 sourceUserId)) { 6341 return null; 6342 } 6343 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 6344 resolvedType, flags, parentUserId); 6345 6346 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 6347 return null; 6348 } 6349 CrossProfileDomainInfo result = null; 6350 int size = resultTargetUser.size(); 6351 for (int i = 0; i < size; i++) { 6352 ResolveInfo riTargetUser = resultTargetUser.get(i); 6353 // Intent filter verification is only for filters that specify a host. So don't return 6354 // those that handle all web uris. 6355 if (riTargetUser.handleAllWebDataURI) { 6356 continue; 6357 } 6358 String packageName = riTargetUser.activityInfo.packageName; 6359 PackageSetting ps = mSettings.mPackages.get(packageName); 6360 if (ps == null) { 6361 continue; 6362 } 6363 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 6364 int status = (int)(verificationState >> 32); 6365 if (result == null) { 6366 result = new CrossProfileDomainInfo(); 6367 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 6368 sourceUserId, parentUserId); 6369 result.bestDomainVerificationStatus = status; 6370 } else { 6371 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 6372 result.bestDomainVerificationStatus); 6373 } 6374 } 6375 // Don't consider matches with status NEVER across profiles. 6376 if (result != null && result.bestDomainVerificationStatus 6377 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6378 return null; 6379 } 6380 return result; 6381 } 6382 6383 /** 6384 * Verification statuses are ordered from the worse to the best, except for 6385 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 6386 */ 6387 private int bestDomainVerificationStatus(int status1, int status2) { 6388 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6389 return status2; 6390 } 6391 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6392 return status1; 6393 } 6394 return (int) MathUtils.max(status1, status2); 6395 } 6396 6397 private boolean isUserEnabled(int userId) { 6398 long callingId = Binder.clearCallingIdentity(); 6399 try { 6400 UserInfo userInfo = sUserManager.getUserInfo(userId); 6401 return userInfo != null && userInfo.isEnabled(); 6402 } finally { 6403 Binder.restoreCallingIdentity(callingId); 6404 } 6405 } 6406 6407 /** 6408 * Filter out activities with systemUserOnly flag set, when current user is not System. 6409 * 6410 * @return filtered list 6411 */ 6412 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 6413 if (userId == UserHandle.USER_SYSTEM) { 6414 return resolveInfos; 6415 } 6416 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 6417 ResolveInfo info = resolveInfos.get(i); 6418 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 6419 resolveInfos.remove(i); 6420 } 6421 } 6422 return resolveInfos; 6423 } 6424 6425 /** 6426 * Filters out ephemeral activities. 6427 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the 6428 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned. 6429 * 6430 * @param resolveInfos The pre-filtered list of resolved activities 6431 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering 6432 * is performed. 6433 * @return A filtered list of resolved activities. 6434 */ 6435 private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos, 6436 String ephemeralPkgName) { 6437 // TODO: When adding on-demand split support for non-instant apps, remove this check 6438 // and always apply post filtering 6439 if (ephemeralPkgName == null) { 6440 return resolveInfos; 6441 } 6442 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 6443 final ResolveInfo info = resolveInfos.get(i); 6444 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp(); 6445 // allow activities that are defined in the provided package 6446 if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) { 6447 if (info.activityInfo.splitName != null 6448 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames, 6449 info.activityInfo.splitName)) { 6450 // requested activity is defined in a split that hasn't been installed yet. 6451 // add the installer to the resolve list 6452 if (DEBUG_EPHEMERAL) { 6453 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 6454 } 6455 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo); 6456 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo( 6457 info.activityInfo.packageName, info.activityInfo.splitName, 6458 info.activityInfo.applicationInfo.versionCode); 6459 // make sure this resolver is the default 6460 installerInfo.isDefault = true; 6461 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 6462 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 6463 // add a non-generic filter 6464 installerInfo.filter = new IntentFilter(); 6465 // load resources from the correct package 6466 installerInfo.resolvePackageName = info.getComponentInfo().packageName; 6467 resolveInfos.set(i, installerInfo); 6468 } 6469 continue; 6470 } 6471 // allow activities that have been explicitly exposed to ephemeral apps 6472 if (!isEphemeralApp 6473 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) { 6474 continue; 6475 } 6476 resolveInfos.remove(i); 6477 } 6478 return resolveInfos; 6479 } 6480 6481 /** 6482 * @param resolveInfos list of resolve infos in descending priority order 6483 * @return if the list contains a resolve info with non-negative priority 6484 */ 6485 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 6486 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 6487 } 6488 6489 private static boolean hasWebURI(Intent intent) { 6490 if (intent.getData() == null) { 6491 return false; 6492 } 6493 final String scheme = intent.getScheme(); 6494 if (TextUtils.isEmpty(scheme)) { 6495 return false; 6496 } 6497 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 6498 } 6499 6500 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 6501 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 6502 int userId) { 6503 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 6504 6505 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 6506 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 6507 candidates.size()); 6508 } 6509 6510 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 6511 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 6512 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 6513 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 6514 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 6515 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 6516 6517 synchronized (mPackages) { 6518 final int count = candidates.size(); 6519 // First, try to use linked apps. Partition the candidates into four lists: 6520 // one for the final results, one for the "do not use ever", one for "undefined status" 6521 // and finally one for "browser app type". 6522 for (int n=0; n<count; n++) { 6523 ResolveInfo info = candidates.get(n); 6524 String packageName = info.activityInfo.packageName; 6525 PackageSetting ps = mSettings.mPackages.get(packageName); 6526 if (ps != null) { 6527 // Add to the special match all list (Browser use case) 6528 if (info.handleAllWebDataURI) { 6529 matchAllList.add(info); 6530 continue; 6531 } 6532 // Try to get the status from User settings first 6533 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 6534 int status = (int)(packedStatus >> 32); 6535 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 6536 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 6537 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6538 Slog.i(TAG, " + always: " + info.activityInfo.packageName 6539 + " : linkgen=" + linkGeneration); 6540 } 6541 // Use link-enabled generation as preferredOrder, i.e. 6542 // prefer newly-enabled over earlier-enabled. 6543 info.preferredOrder = linkGeneration; 6544 alwaysList.add(info); 6545 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6546 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6547 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 6548 } 6549 neverList.add(info); 6550 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 6551 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6552 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 6553 } 6554 alwaysAskList.add(info); 6555 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 6556 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 6557 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6558 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 6559 } 6560 undefinedList.add(info); 6561 } 6562 } 6563 } 6564 6565 // We'll want to include browser possibilities in a few cases 6566 boolean includeBrowser = false; 6567 6568 // First try to add the "always" resolution(s) for the current user, if any 6569 if (alwaysList.size() > 0) { 6570 result.addAll(alwaysList); 6571 } else { 6572 // Add all undefined apps as we want them to appear in the disambiguation dialog. 6573 result.addAll(undefinedList); 6574 // Maybe add one for the other profile. 6575 if (xpDomainInfo != null && ( 6576 xpDomainInfo.bestDomainVerificationStatus 6577 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 6578 result.add(xpDomainInfo.resolveInfo); 6579 } 6580 includeBrowser = true; 6581 } 6582 6583 // The presence of any 'always ask' alternatives means we'll also offer browsers. 6584 // If there were 'always' entries their preferred order has been set, so we also 6585 // back that off to make the alternatives equivalent 6586 if (alwaysAskList.size() > 0) { 6587 for (ResolveInfo i : result) { 6588 i.preferredOrder = 0; 6589 } 6590 result.addAll(alwaysAskList); 6591 includeBrowser = true; 6592 } 6593 6594 if (includeBrowser) { 6595 // Also add browsers (all of them or only the default one) 6596 if (DEBUG_DOMAIN_VERIFICATION) { 6597 Slog.v(TAG, " ...including browsers in candidate set"); 6598 } 6599 if ((matchFlags & MATCH_ALL) != 0) { 6600 result.addAll(matchAllList); 6601 } else { 6602 // Browser/generic handling case. If there's a default browser, go straight 6603 // to that (but only if there is no other higher-priority match). 6604 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 6605 int maxMatchPrio = 0; 6606 ResolveInfo defaultBrowserMatch = null; 6607 final int numCandidates = matchAllList.size(); 6608 for (int n = 0; n < numCandidates; n++) { 6609 ResolveInfo info = matchAllList.get(n); 6610 // track the highest overall match priority... 6611 if (info.priority > maxMatchPrio) { 6612 maxMatchPrio = info.priority; 6613 } 6614 // ...and the highest-priority default browser match 6615 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 6616 if (defaultBrowserMatch == null 6617 || (defaultBrowserMatch.priority < info.priority)) { 6618 if (debug) { 6619 Slog.v(TAG, "Considering default browser match " + info); 6620 } 6621 defaultBrowserMatch = info; 6622 } 6623 } 6624 } 6625 if (defaultBrowserMatch != null 6626 && defaultBrowserMatch.priority >= maxMatchPrio 6627 && !TextUtils.isEmpty(defaultBrowserPackageName)) 6628 { 6629 if (debug) { 6630 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 6631 } 6632 result.add(defaultBrowserMatch); 6633 } else { 6634 result.addAll(matchAllList); 6635 } 6636 } 6637 6638 // If there is nothing selected, add all candidates and remove the ones that the user 6639 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 6640 if (result.size() == 0) { 6641 result.addAll(candidates); 6642 result.removeAll(neverList); 6643 } 6644 } 6645 } 6646 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 6647 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 6648 result.size()); 6649 for (ResolveInfo info : result) { 6650 Slog.v(TAG, " + " + info.activityInfo); 6651 } 6652 } 6653 return result; 6654 } 6655 6656 // Returns a packed value as a long: 6657 // 6658 // high 'int'-sized word: link status: undefined/ask/never/always. 6659 // low 'int'-sized word: relative priority among 'always' results. 6660 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 6661 long result = ps.getDomainVerificationStatusForUser(userId); 6662 // if none available, get the master status 6663 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 6664 if (ps.getIntentFilterVerificationInfo() != null) { 6665 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 6666 } 6667 } 6668 return result; 6669 } 6670 6671 private ResolveInfo querySkipCurrentProfileIntents( 6672 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6673 int flags, int sourceUserId) { 6674 if (matchingFilters != null) { 6675 int size = matchingFilters.size(); 6676 for (int i = 0; i < size; i ++) { 6677 CrossProfileIntentFilter filter = matchingFilters.get(i); 6678 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 6679 // Checking if there are activities in the target user that can handle the 6680 // intent. 6681 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6682 resolvedType, flags, sourceUserId); 6683 if (resolveInfo != null) { 6684 return resolveInfo; 6685 } 6686 } 6687 } 6688 } 6689 return null; 6690 } 6691 6692 // Return matching ResolveInfo in target user if any. 6693 private ResolveInfo queryCrossProfileIntents( 6694 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6695 int flags, int sourceUserId, boolean matchInCurrentProfile) { 6696 if (matchingFilters != null) { 6697 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 6698 // match the same intent. For performance reasons, it is better not to 6699 // run queryIntent twice for the same userId 6700 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 6701 int size = matchingFilters.size(); 6702 for (int i = 0; i < size; i++) { 6703 CrossProfileIntentFilter filter = matchingFilters.get(i); 6704 int targetUserId = filter.getTargetUserId(); 6705 boolean skipCurrentProfile = 6706 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 6707 boolean skipCurrentProfileIfNoMatchFound = 6708 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 6709 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 6710 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 6711 // Checking if there are activities in the target user that can handle the 6712 // intent. 6713 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6714 resolvedType, flags, sourceUserId); 6715 if (resolveInfo != null) return resolveInfo; 6716 alreadyTriedUserIds.put(targetUserId, true); 6717 } 6718 } 6719 } 6720 return null; 6721 } 6722 6723 /** 6724 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 6725 * will forward the intent to the filter's target user. 6726 * Otherwise, returns null. 6727 */ 6728 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 6729 String resolvedType, int flags, int sourceUserId) { 6730 int targetUserId = filter.getTargetUserId(); 6731 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 6732 resolvedType, flags, targetUserId); 6733 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 6734 // If all the matches in the target profile are suspended, return null. 6735 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 6736 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 6737 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 6738 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 6739 targetUserId); 6740 } 6741 } 6742 } 6743 return null; 6744 } 6745 6746 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 6747 int sourceUserId, int targetUserId) { 6748 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 6749 long ident = Binder.clearCallingIdentity(); 6750 boolean targetIsProfile; 6751 try { 6752 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 6753 } finally { 6754 Binder.restoreCallingIdentity(ident); 6755 } 6756 String className; 6757 if (targetIsProfile) { 6758 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 6759 } else { 6760 className = FORWARD_INTENT_TO_PARENT; 6761 } 6762 ComponentName forwardingActivityComponentName = new ComponentName( 6763 mAndroidApplication.packageName, className); 6764 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 6765 sourceUserId); 6766 if (!targetIsProfile) { 6767 forwardingActivityInfo.showUserIcon = targetUserId; 6768 forwardingResolveInfo.noResourceId = true; 6769 } 6770 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 6771 forwardingResolveInfo.priority = 0; 6772 forwardingResolveInfo.preferredOrder = 0; 6773 forwardingResolveInfo.match = 0; 6774 forwardingResolveInfo.isDefault = true; 6775 forwardingResolveInfo.filter = filter; 6776 forwardingResolveInfo.targetUserId = targetUserId; 6777 return forwardingResolveInfo; 6778 } 6779 6780 @Override 6781 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 6782 Intent[] specifics, String[] specificTypes, Intent intent, 6783 String resolvedType, int flags, int userId) { 6784 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 6785 specificTypes, intent, resolvedType, flags, userId)); 6786 } 6787 6788 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 6789 Intent[] specifics, String[] specificTypes, Intent intent, 6790 String resolvedType, int flags, int userId) { 6791 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6792 flags = updateFlagsForResolve(flags, userId, intent, false); 6793 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6794 false /* requireFullPermission */, false /* checkShell */, 6795 "query intent activity options"); 6796 final String resultsAction = intent.getAction(); 6797 6798 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 6799 | PackageManager.GET_RESOLVED_FILTER, userId); 6800 6801 if (DEBUG_INTENT_MATCHING) { 6802 Log.v(TAG, "Query " + intent + ": " + results); 6803 } 6804 6805 int specificsPos = 0; 6806 int N; 6807 6808 // todo: note that the algorithm used here is O(N^2). This 6809 // isn't a problem in our current environment, but if we start running 6810 // into situations where we have more than 5 or 10 matches then this 6811 // should probably be changed to something smarter... 6812 6813 // First we go through and resolve each of the specific items 6814 // that were supplied, taking care of removing any corresponding 6815 // duplicate items in the generic resolve list. 6816 if (specifics != null) { 6817 for (int i=0; i<specifics.length; i++) { 6818 final Intent sintent = specifics[i]; 6819 if (sintent == null) { 6820 continue; 6821 } 6822 6823 if (DEBUG_INTENT_MATCHING) { 6824 Log.v(TAG, "Specific #" + i + ": " + sintent); 6825 } 6826 6827 String action = sintent.getAction(); 6828 if (resultsAction != null && resultsAction.equals(action)) { 6829 // If this action was explicitly requested, then don't 6830 // remove things that have it. 6831 action = null; 6832 } 6833 6834 ResolveInfo ri = null; 6835 ActivityInfo ai = null; 6836 6837 ComponentName comp = sintent.getComponent(); 6838 if (comp == null) { 6839 ri = resolveIntent( 6840 sintent, 6841 specificTypes != null ? specificTypes[i] : null, 6842 flags, userId); 6843 if (ri == null) { 6844 continue; 6845 } 6846 if (ri == mResolveInfo) { 6847 // ACK! Must do something better with this. 6848 } 6849 ai = ri.activityInfo; 6850 comp = new ComponentName(ai.applicationInfo.packageName, 6851 ai.name); 6852 } else { 6853 ai = getActivityInfo(comp, flags, userId); 6854 if (ai == null) { 6855 continue; 6856 } 6857 } 6858 6859 // Look for any generic query activities that are duplicates 6860 // of this specific one, and remove them from the results. 6861 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 6862 N = results.size(); 6863 int j; 6864 for (j=specificsPos; j<N; j++) { 6865 ResolveInfo sri = results.get(j); 6866 if ((sri.activityInfo.name.equals(comp.getClassName()) 6867 && sri.activityInfo.applicationInfo.packageName.equals( 6868 comp.getPackageName())) 6869 || (action != null && sri.filter.matchAction(action))) { 6870 results.remove(j); 6871 if (DEBUG_INTENT_MATCHING) Log.v( 6872 TAG, "Removing duplicate item from " + j 6873 + " due to specific " + specificsPos); 6874 if (ri == null) { 6875 ri = sri; 6876 } 6877 j--; 6878 N--; 6879 } 6880 } 6881 6882 // Add this specific item to its proper place. 6883 if (ri == null) { 6884 ri = new ResolveInfo(); 6885 ri.activityInfo = ai; 6886 } 6887 results.add(specificsPos, ri); 6888 ri.specificIndex = i; 6889 specificsPos++; 6890 } 6891 } 6892 6893 // Now we go through the remaining generic results and remove any 6894 // duplicate actions that are found here. 6895 N = results.size(); 6896 for (int i=specificsPos; i<N-1; i++) { 6897 final ResolveInfo rii = results.get(i); 6898 if (rii.filter == null) { 6899 continue; 6900 } 6901 6902 // Iterate over all of the actions of this result's intent 6903 // filter... typically this should be just one. 6904 final Iterator<String> it = rii.filter.actionsIterator(); 6905 if (it == null) { 6906 continue; 6907 } 6908 while (it.hasNext()) { 6909 final String action = it.next(); 6910 if (resultsAction != null && resultsAction.equals(action)) { 6911 // If this action was explicitly requested, then don't 6912 // remove things that have it. 6913 continue; 6914 } 6915 for (int j=i+1; j<N; j++) { 6916 final ResolveInfo rij = results.get(j); 6917 if (rij.filter != null && rij.filter.hasAction(action)) { 6918 results.remove(j); 6919 if (DEBUG_INTENT_MATCHING) Log.v( 6920 TAG, "Removing duplicate item from " + j 6921 + " due to action " + action + " at " + i); 6922 j--; 6923 N--; 6924 } 6925 } 6926 } 6927 6928 // If the caller didn't request filter information, drop it now 6929 // so we don't have to marshall/unmarshall it. 6930 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6931 rii.filter = null; 6932 } 6933 } 6934 6935 // Filter out the caller activity if so requested. 6936 if (caller != null) { 6937 N = results.size(); 6938 for (int i=0; i<N; i++) { 6939 ActivityInfo ainfo = results.get(i).activityInfo; 6940 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 6941 && caller.getClassName().equals(ainfo.name)) { 6942 results.remove(i); 6943 break; 6944 } 6945 } 6946 } 6947 6948 // If the caller didn't request filter information, 6949 // drop them now so we don't have to 6950 // marshall/unmarshall it. 6951 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6952 N = results.size(); 6953 for (int i=0; i<N; i++) { 6954 results.get(i).filter = null; 6955 } 6956 } 6957 6958 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 6959 return results; 6960 } 6961 6962 @Override 6963 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 6964 String resolvedType, int flags, int userId) { 6965 return new ParceledListSlice<>( 6966 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 6967 } 6968 6969 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 6970 String resolvedType, int flags, int userId) { 6971 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6972 flags = updateFlagsForResolve(flags, userId, intent, false); 6973 ComponentName comp = intent.getComponent(); 6974 if (comp == null) { 6975 if (intent.getSelector() != null) { 6976 intent = intent.getSelector(); 6977 comp = intent.getComponent(); 6978 } 6979 } 6980 if (comp != null) { 6981 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6982 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 6983 if (ai != null) { 6984 ResolveInfo ri = new ResolveInfo(); 6985 ri.activityInfo = ai; 6986 list.add(ri); 6987 } 6988 return list; 6989 } 6990 6991 // reader 6992 synchronized (mPackages) { 6993 String pkgName = intent.getPackage(); 6994 if (pkgName == null) { 6995 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 6996 } 6997 final PackageParser.Package pkg = mPackages.get(pkgName); 6998 if (pkg != null) { 6999 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 7000 userId); 7001 } 7002 return Collections.emptyList(); 7003 } 7004 } 7005 7006 @Override 7007 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 7008 if (!sUserManager.exists(userId)) return null; 7009 flags = updateFlagsForResolve(flags, userId, intent, false); 7010 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 7011 if (query != null) { 7012 if (query.size() >= 1) { 7013 // If there is more than one service with the same priority, 7014 // just arbitrarily pick the first one. 7015 return query.get(0); 7016 } 7017 } 7018 return null; 7019 } 7020 7021 @Override 7022 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 7023 String resolvedType, int flags, int userId) { 7024 return new ParceledListSlice<>( 7025 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 7026 } 7027 7028 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 7029 String resolvedType, int flags, int userId) { 7030 if (!sUserManager.exists(userId)) return Collections.emptyList(); 7031 flags = updateFlagsForResolve(flags, userId, intent, false); 7032 ComponentName comp = intent.getComponent(); 7033 if (comp == null) { 7034 if (intent.getSelector() != null) { 7035 intent = intent.getSelector(); 7036 comp = intent.getComponent(); 7037 } 7038 } 7039 if (comp != null) { 7040 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 7041 final ServiceInfo si = getServiceInfo(comp, flags, userId); 7042 if (si != null) { 7043 final ResolveInfo ri = new ResolveInfo(); 7044 ri.serviceInfo = si; 7045 list.add(ri); 7046 } 7047 return list; 7048 } 7049 7050 // reader 7051 synchronized (mPackages) { 7052 String pkgName = intent.getPackage(); 7053 if (pkgName == null) { 7054 return mServices.queryIntent(intent, resolvedType, flags, userId); 7055 } 7056 final PackageParser.Package pkg = mPackages.get(pkgName); 7057 if (pkg != null) { 7058 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 7059 userId); 7060 } 7061 return Collections.emptyList(); 7062 } 7063 } 7064 7065 @Override 7066 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 7067 String resolvedType, int flags, int userId) { 7068 return new ParceledListSlice<>( 7069 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 7070 } 7071 7072 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 7073 Intent intent, String resolvedType, int flags, int userId) { 7074 if (!sUserManager.exists(userId)) return Collections.emptyList(); 7075 flags = updateFlagsForResolve(flags, userId, intent, false); 7076 ComponentName comp = intent.getComponent(); 7077 if (comp == null) { 7078 if (intent.getSelector() != null) { 7079 intent = intent.getSelector(); 7080 comp = intent.getComponent(); 7081 } 7082 } 7083 if (comp != null) { 7084 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 7085 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 7086 if (pi != null) { 7087 final ResolveInfo ri = new ResolveInfo(); 7088 ri.providerInfo = pi; 7089 list.add(ri); 7090 } 7091 return list; 7092 } 7093 7094 // reader 7095 synchronized (mPackages) { 7096 String pkgName = intent.getPackage(); 7097 if (pkgName == null) { 7098 return mProviders.queryIntent(intent, resolvedType, flags, userId); 7099 } 7100 final PackageParser.Package pkg = mPackages.get(pkgName); 7101 if (pkg != null) { 7102 return mProviders.queryIntentForPackage( 7103 intent, resolvedType, flags, pkg.providers, userId); 7104 } 7105 return Collections.emptyList(); 7106 } 7107 } 7108 7109 @Override 7110 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 7111 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7112 flags = updateFlagsForPackage(flags, userId, null); 7113 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 7114 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7115 true /* requireFullPermission */, false /* checkShell */, 7116 "get installed packages"); 7117 7118 // writer 7119 synchronized (mPackages) { 7120 ArrayList<PackageInfo> list; 7121 if (listUninstalled) { 7122 list = new ArrayList<>(mSettings.mPackages.size()); 7123 for (PackageSetting ps : mSettings.mPackages.values()) { 7124 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7125 continue; 7126 } 7127 final PackageInfo pi = generatePackageInfo(ps, flags, userId); 7128 if (pi != null) { 7129 list.add(pi); 7130 } 7131 } 7132 } else { 7133 list = new ArrayList<>(mPackages.size()); 7134 for (PackageParser.Package p : mPackages.values()) { 7135 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras, 7136 Binder.getCallingUid(), userId)) { 7137 continue; 7138 } 7139 final PackageInfo pi = generatePackageInfo((PackageSetting) 7140 p.mExtras, flags, userId); 7141 if (pi != null) { 7142 list.add(pi); 7143 } 7144 } 7145 } 7146 7147 return new ParceledListSlice<>(list); 7148 } 7149 } 7150 7151 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 7152 String[] permissions, boolean[] tmp, int flags, int userId) { 7153 int numMatch = 0; 7154 final PermissionsState permissionsState = ps.getPermissionsState(); 7155 for (int i=0; i<permissions.length; i++) { 7156 final String permission = permissions[i]; 7157 if (permissionsState.hasPermission(permission, userId)) { 7158 tmp[i] = true; 7159 numMatch++; 7160 } else { 7161 tmp[i] = false; 7162 } 7163 } 7164 if (numMatch == 0) { 7165 return; 7166 } 7167 final PackageInfo pi = generatePackageInfo(ps, flags, userId); 7168 7169 // The above might return null in cases of uninstalled apps or install-state 7170 // skew across users/profiles. 7171 if (pi != null) { 7172 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 7173 if (numMatch == permissions.length) { 7174 pi.requestedPermissions = permissions; 7175 } else { 7176 pi.requestedPermissions = new String[numMatch]; 7177 numMatch = 0; 7178 for (int i=0; i<permissions.length; i++) { 7179 if (tmp[i]) { 7180 pi.requestedPermissions[numMatch] = permissions[i]; 7181 numMatch++; 7182 } 7183 } 7184 } 7185 } 7186 list.add(pi); 7187 } 7188 } 7189 7190 @Override 7191 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 7192 String[] permissions, int flags, int userId) { 7193 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7194 flags = updateFlagsForPackage(flags, userId, permissions); 7195 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7196 true /* requireFullPermission */, false /* checkShell */, 7197 "get packages holding permissions"); 7198 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 7199 7200 // writer 7201 synchronized (mPackages) { 7202 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 7203 boolean[] tmpBools = new boolean[permissions.length]; 7204 if (listUninstalled) { 7205 for (PackageSetting ps : mSettings.mPackages.values()) { 7206 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 7207 userId); 7208 } 7209 } else { 7210 for (PackageParser.Package pkg : mPackages.values()) { 7211 PackageSetting ps = (PackageSetting)pkg.mExtras; 7212 if (ps != null) { 7213 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 7214 userId); 7215 } 7216 } 7217 } 7218 7219 return new ParceledListSlice<PackageInfo>(list); 7220 } 7221 } 7222 7223 @Override 7224 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 7225 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7226 flags = updateFlagsForApplication(flags, userId, null); 7227 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 7228 7229 // writer 7230 synchronized (mPackages) { 7231 ArrayList<ApplicationInfo> list; 7232 if (listUninstalled) { 7233 list = new ArrayList<>(mSettings.mPackages.size()); 7234 for (PackageSetting ps : mSettings.mPackages.values()) { 7235 ApplicationInfo ai; 7236 int effectiveFlags = flags; 7237 if (ps.isSystem()) { 7238 effectiveFlags |= PackageManager.MATCH_ANY_USER; 7239 } 7240 if (ps.pkg != null) { 7241 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7242 continue; 7243 } 7244 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags, 7245 ps.readUserState(userId), userId); 7246 if (ai != null) { 7247 rebaseEnabledOverlays(ai, userId); 7248 ai.packageName = resolveExternalPackageNameLPr(ps.pkg); 7249 } 7250 } else { 7251 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw 7252 // and already converts to externally visible package name 7253 ai = generateApplicationInfoFromSettingsLPw(ps.name, 7254 Binder.getCallingUid(), effectiveFlags, userId); 7255 } 7256 if (ai != null) { 7257 list.add(ai); 7258 } 7259 } 7260 } else { 7261 list = new ArrayList<>(mPackages.size()); 7262 for (PackageParser.Package p : mPackages.values()) { 7263 if (p.mExtras != null) { 7264 PackageSetting ps = (PackageSetting) p.mExtras; 7265 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7266 continue; 7267 } 7268 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 7269 ps.readUserState(userId), userId); 7270 if (ai != null) { 7271 rebaseEnabledOverlays(ai, userId); 7272 ai.packageName = resolveExternalPackageNameLPr(p); 7273 list.add(ai); 7274 } 7275 } 7276 } 7277 } 7278 7279 return new ParceledListSlice<>(list); 7280 } 7281 } 7282 7283 @Override 7284 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) { 7285 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7286 return null; 7287 } 7288 7289 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, 7290 "getEphemeralApplications"); 7291 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7292 true /* requireFullPermission */, false /* checkShell */, 7293 "getEphemeralApplications"); 7294 synchronized (mPackages) { 7295 List<InstantAppInfo> instantApps = mInstantAppRegistry 7296 .getInstantAppsLPr(userId); 7297 if (instantApps != null) { 7298 return new ParceledListSlice<>(instantApps); 7299 } 7300 } 7301 return null; 7302 } 7303 7304 @Override 7305 public boolean isInstantApp(String packageName, int userId) { 7306 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7307 true /* requireFullPermission */, false /* checkShell */, 7308 "isInstantApp"); 7309 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7310 return false; 7311 } 7312 7313 synchronized (mPackages) { 7314 final PackageSetting ps = mSettings.mPackages.get(packageName); 7315 final boolean returnAllowed = 7316 ps != null 7317 && (isCallerSameApp(packageName) 7318 || mContext.checkCallingOrSelfPermission( 7319 android.Manifest.permission.ACCESS_INSTANT_APPS) 7320 == PERMISSION_GRANTED 7321 || mInstantAppRegistry.isInstantAccessGranted( 7322 userId, UserHandle.getAppId(Binder.getCallingUid()), ps.appId)); 7323 if (returnAllowed) { 7324 return ps.getInstantApp(userId); 7325 } 7326 } 7327 return false; 7328 } 7329 7330 @Override 7331 public byte[] getInstantAppCookie(String packageName, int userId) { 7332 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7333 return null; 7334 } 7335 7336 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7337 true /* requireFullPermission */, false /* checkShell */, 7338 "getInstantAppCookie"); 7339 if (!isCallerSameApp(packageName)) { 7340 return null; 7341 } 7342 synchronized (mPackages) { 7343 return mInstantAppRegistry.getInstantAppCookieLPw( 7344 packageName, userId); 7345 } 7346 } 7347 7348 @Override 7349 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) { 7350 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7351 return true; 7352 } 7353 7354 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7355 true /* requireFullPermission */, true /* checkShell */, 7356 "setInstantAppCookie"); 7357 if (!isCallerSameApp(packageName)) { 7358 return false; 7359 } 7360 synchronized (mPackages) { 7361 return mInstantAppRegistry.setInstantAppCookieLPw( 7362 packageName, cookie, userId); 7363 } 7364 } 7365 7366 @Override 7367 public Bitmap getInstantAppIcon(String packageName, int userId) { 7368 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7369 return null; 7370 } 7371 7372 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, 7373 "getInstantAppIcon"); 7374 7375 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7376 true /* requireFullPermission */, false /* checkShell */, 7377 "getInstantAppIcon"); 7378 7379 synchronized (mPackages) { 7380 return mInstantAppRegistry.getInstantAppIconLPw( 7381 packageName, userId); 7382 } 7383 } 7384 7385 private boolean isCallerSameApp(String packageName) { 7386 PackageParser.Package pkg = mPackages.get(packageName); 7387 return pkg != null 7388 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 7389 } 7390 7391 @Override 7392 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 7393 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 7394 } 7395 7396 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 7397 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 7398 7399 // reader 7400 synchronized (mPackages) { 7401 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 7402 final int userId = UserHandle.getCallingUserId(); 7403 while (i.hasNext()) { 7404 final PackageParser.Package p = i.next(); 7405 if (p.applicationInfo == null) continue; 7406 7407 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 7408 && !p.applicationInfo.isDirectBootAware(); 7409 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 7410 && p.applicationInfo.isDirectBootAware(); 7411 7412 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 7413 && (!mSafeMode || isSystemApp(p)) 7414 && (matchesUnaware || matchesAware)) { 7415 PackageSetting ps = mSettings.mPackages.get(p.packageName); 7416 if (ps != null) { 7417 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 7418 ps.readUserState(userId), userId); 7419 if (ai != null) { 7420 rebaseEnabledOverlays(ai, userId); 7421 finalList.add(ai); 7422 } 7423 } 7424 } 7425 } 7426 } 7427 7428 return finalList; 7429 } 7430 7431 @Override 7432 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 7433 if (!sUserManager.exists(userId)) return null; 7434 flags = updateFlagsForComponent(flags, userId, name); 7435 // reader 7436 synchronized (mPackages) { 7437 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 7438 PackageSetting ps = provider != null 7439 ? mSettings.mPackages.get(provider.owner.packageName) 7440 : null; 7441 return ps != null 7442 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 7443 ? PackageParser.generateProviderInfo(provider, flags, 7444 ps.readUserState(userId), userId) 7445 : null; 7446 } 7447 } 7448 7449 /** 7450 * @deprecated 7451 */ 7452 @Deprecated 7453 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 7454 // reader 7455 synchronized (mPackages) { 7456 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 7457 .entrySet().iterator(); 7458 final int userId = UserHandle.getCallingUserId(); 7459 while (i.hasNext()) { 7460 Map.Entry<String, PackageParser.Provider> entry = i.next(); 7461 PackageParser.Provider p = entry.getValue(); 7462 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 7463 7464 if (ps != null && p.syncable 7465 && (!mSafeMode || (p.info.applicationInfo.flags 7466 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 7467 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 7468 ps.readUserState(userId), userId); 7469 if (info != null) { 7470 outNames.add(entry.getKey()); 7471 outInfo.add(info); 7472 } 7473 } 7474 } 7475 } 7476 } 7477 7478 @Override 7479 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 7480 int uid, int flags, String metaDataKey) { 7481 final int userId = processName != null ? UserHandle.getUserId(uid) 7482 : UserHandle.getCallingUserId(); 7483 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7484 flags = updateFlagsForComponent(flags, userId, processName); 7485 7486 ArrayList<ProviderInfo> finalList = null; 7487 // reader 7488 synchronized (mPackages) { 7489 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 7490 while (i.hasNext()) { 7491 final PackageParser.Provider p = i.next(); 7492 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 7493 if (ps != null && p.info.authority != null 7494 && (processName == null 7495 || (p.info.processName.equals(processName) 7496 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 7497 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 7498 7499 // See PM.queryContentProviders()'s javadoc for why we have the metaData 7500 // parameter. 7501 if (metaDataKey != null 7502 && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) { 7503 continue; 7504 } 7505 7506 if (finalList == null) { 7507 finalList = new ArrayList<ProviderInfo>(3); 7508 } 7509 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 7510 ps.readUserState(userId), userId); 7511 if (info != null) { 7512 finalList.add(info); 7513 } 7514 } 7515 } 7516 } 7517 7518 if (finalList != null) { 7519 Collections.sort(finalList, mProviderInitOrderSorter); 7520 return new ParceledListSlice<ProviderInfo>(finalList); 7521 } 7522 7523 return ParceledListSlice.emptyList(); 7524 } 7525 7526 @Override 7527 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 7528 // reader 7529 synchronized (mPackages) { 7530 final PackageParser.Instrumentation i = mInstrumentation.get(name); 7531 return PackageParser.generateInstrumentationInfo(i, flags); 7532 } 7533 } 7534 7535 @Override 7536 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 7537 String targetPackage, int flags) { 7538 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 7539 } 7540 7541 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 7542 int flags) { 7543 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 7544 7545 // reader 7546 synchronized (mPackages) { 7547 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 7548 while (i.hasNext()) { 7549 final PackageParser.Instrumentation p = i.next(); 7550 if (targetPackage == null 7551 || targetPackage.equals(p.info.targetPackage)) { 7552 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 7553 flags); 7554 if (ii != null) { 7555 finalList.add(ii); 7556 } 7557 } 7558 } 7559 } 7560 7561 return finalList; 7562 } 7563 7564 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 7565 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]"); 7566 try { 7567 scanDirLI(dir, parseFlags, scanFlags, currentTime); 7568 } finally { 7569 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7570 } 7571 } 7572 7573 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 7574 final File[] files = dir.listFiles(); 7575 if (ArrayUtils.isEmpty(files)) { 7576 Log.d(TAG, "No files in app dir " + dir); 7577 return; 7578 } 7579 7580 if (DEBUG_PACKAGE_SCANNING) { 7581 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 7582 + " flags=0x" + Integer.toHexString(parseFlags)); 7583 } 7584 ParallelPackageParser parallelPackageParser = new ParallelPackageParser( 7585 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback); 7586 7587 // Submit files for parsing in parallel 7588 int fileCount = 0; 7589 for (File file : files) { 7590 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 7591 && !PackageInstallerService.isStageName(file.getName()); 7592 if (!isPackage) { 7593 // Ignore entries which are not packages 7594 continue; 7595 } 7596 parallelPackageParser.submit(file, parseFlags); 7597 fileCount++; 7598 } 7599 7600 // Process results one by one 7601 for (; fileCount > 0; fileCount--) { 7602 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); 7603 Throwable throwable = parseResult.throwable; 7604 int errorCode = PackageManager.INSTALL_SUCCEEDED; 7605 7606 if (throwable == null) { 7607 // Static shared libraries have synthetic package names 7608 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) { 7609 renameStaticSharedLibraryPackage(parseResult.pkg); 7610 } 7611 try { 7612 if (errorCode == PackageManager.INSTALL_SUCCEEDED) { 7613 scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags, 7614 currentTime, null); 7615 } 7616 } catch (PackageManagerException e) { 7617 errorCode = e.error; 7618 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage()); 7619 } 7620 } else if (throwable instanceof PackageParser.PackageParserException) { 7621 PackageParser.PackageParserException e = (PackageParser.PackageParserException) 7622 throwable; 7623 errorCode = e.error; 7624 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage()); 7625 } else { 7626 throw new IllegalStateException("Unexpected exception occurred while parsing " 7627 + parseResult.scanFile, throwable); 7628 } 7629 7630 // Delete invalid userdata apps 7631 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 7632 errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) { 7633 logCriticalInfo(Log.WARN, 7634 "Deleting invalid package at " + parseResult.scanFile); 7635 removeCodePathLI(parseResult.scanFile); 7636 } 7637 } 7638 parallelPackageParser.close(); 7639 } 7640 7641 private static File getSettingsProblemFile() { 7642 File dataDir = Environment.getDataDirectory(); 7643 File systemDir = new File(dataDir, "system"); 7644 File fname = new File(systemDir, "uiderrors.txt"); 7645 return fname; 7646 } 7647 7648 static void reportSettingsProblem(int priority, String msg) { 7649 logCriticalInfo(priority, msg); 7650 } 7651 7652 public static void logCriticalInfo(int priority, String msg) { 7653 Slog.println(priority, TAG, msg); 7654 EventLogTags.writePmCriticalInfo(msg); 7655 try { 7656 File fname = getSettingsProblemFile(); 7657 FileOutputStream out = new FileOutputStream(fname, true); 7658 PrintWriter pw = new FastPrintWriter(out); 7659 SimpleDateFormat formatter = new SimpleDateFormat(); 7660 String dateString = formatter.format(new Date(System.currentTimeMillis())); 7661 pw.println(dateString + ": " + msg); 7662 pw.close(); 7663 FileUtils.setPermissions( 7664 fname.toString(), 7665 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 7666 -1, -1); 7667 } catch (java.io.IOException e) { 7668 } 7669 } 7670 7671 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 7672 if (srcFile.isDirectory()) { 7673 final File baseFile = new File(pkg.baseCodePath); 7674 long maxModifiedTime = baseFile.lastModified(); 7675 if (pkg.splitCodePaths != null) { 7676 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 7677 final File splitFile = new File(pkg.splitCodePaths[i]); 7678 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 7679 } 7680 } 7681 return maxModifiedTime; 7682 } 7683 return srcFile.lastModified(); 7684 } 7685 7686 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 7687 final int policyFlags) throws PackageManagerException { 7688 // When upgrading from pre-N MR1, verify the package time stamp using the package 7689 // directory and not the APK file. 7690 final long lastModifiedTime = mIsPreNMR1Upgrade 7691 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile); 7692 if (ps != null 7693 && ps.codePath.equals(srcFile) 7694 && ps.timeStamp == lastModifiedTime 7695 && !isCompatSignatureUpdateNeeded(pkg) 7696 && !isRecoverSignatureUpdateNeeded(pkg)) { 7697 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 7698 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7699 ArraySet<PublicKey> signingKs; 7700 synchronized (mPackages) { 7701 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 7702 } 7703 if (ps.signatures.mSignatures != null 7704 && ps.signatures.mSignatures.length != 0 7705 && signingKs != null) { 7706 // Optimization: reuse the existing cached certificates 7707 // if the package appears to be unchanged. 7708 pkg.mSignatures = ps.signatures.mSignatures; 7709 pkg.mSigningKeys = signingKs; 7710 return; 7711 } 7712 7713 Slog.w(TAG, "PackageSetting for " + ps.name 7714 + " is missing signatures. Collecting certs again to recover them."); 7715 } else { 7716 Slog.i(TAG, srcFile.toString() + " changed; collecting certs"); 7717 } 7718 7719 try { 7720 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 7721 PackageParser.collectCertificates(pkg, policyFlags); 7722 } catch (PackageParserException e) { 7723 throw PackageManagerException.from(e); 7724 } finally { 7725 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7726 } 7727 } 7728 7729 /** 7730 * Traces a package scan. 7731 * @see #scanPackageLI(File, int, int, long, UserHandle) 7732 */ 7733 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 7734 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7735 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 7736 try { 7737 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 7738 } finally { 7739 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7740 } 7741 } 7742 7743 /** 7744 * Scans a package and returns the newly parsed package. 7745 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 7746 */ 7747 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 7748 long currentTime, UserHandle user) throws PackageManagerException { 7749 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 7750 PackageParser pp = new PackageParser(); 7751 pp.setSeparateProcesses(mSeparateProcesses); 7752 pp.setOnlyCoreApps(mOnlyCore); 7753 pp.setDisplayMetrics(mMetrics); 7754 pp.setCallback(mPackageParserCallback); 7755 7756 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 7757 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 7758 } 7759 7760 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 7761 final PackageParser.Package pkg; 7762 try { 7763 pkg = pp.parsePackage(scanFile, parseFlags); 7764 } catch (PackageParserException e) { 7765 throw PackageManagerException.from(e); 7766 } finally { 7767 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7768 } 7769 7770 // Static shared libraries have synthetic package names 7771 if (pkg.applicationInfo.isStaticSharedLibrary()) { 7772 renameStaticSharedLibraryPackage(pkg); 7773 } 7774 7775 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 7776 } 7777 7778 /** 7779 * Scans a package and returns the newly parsed package. 7780 * @throws PackageManagerException on a parse error. 7781 */ 7782 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 7783 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 7784 throws PackageManagerException { 7785 // If the package has children and this is the first dive in the function 7786 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 7787 // packages (parent and children) would be successfully scanned before the 7788 // actual scan since scanning mutates internal state and we want to atomically 7789 // install the package and its children. 7790 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7791 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7792 scanFlags |= SCAN_CHECK_ONLY; 7793 } 7794 } else { 7795 scanFlags &= ~SCAN_CHECK_ONLY; 7796 } 7797 7798 // Scan the parent 7799 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 7800 scanFlags, currentTime, user); 7801 7802 // Scan the children 7803 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7804 for (int i = 0; i < childCount; i++) { 7805 PackageParser.Package childPackage = pkg.childPackages.get(i); 7806 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 7807 currentTime, user); 7808 } 7809 7810 7811 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7812 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 7813 } 7814 7815 return scannedPkg; 7816 } 7817 7818 /** 7819 * Scans a package and returns the newly parsed package. 7820 * @throws PackageManagerException on a parse error. 7821 */ 7822 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 7823 int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 7824 throws PackageManagerException { 7825 PackageSetting ps = null; 7826 PackageSetting updatedPkg; 7827 // reader 7828 synchronized (mPackages) { 7829 // Look to see if we already know about this package. 7830 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName); 7831 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 7832 // This package has been renamed to its original name. Let's 7833 // use that. 7834 ps = mSettings.getPackageLPr(oldName); 7835 } 7836 // If there was no original package, see one for the real package name. 7837 if (ps == null) { 7838 ps = mSettings.getPackageLPr(pkg.packageName); 7839 } 7840 // Check to see if this package could be hiding/updating a system 7841 // package. Must look for it either under the original or real 7842 // package name depending on our state. 7843 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 7844 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 7845 7846 // If this is a package we don't know about on the system partition, we 7847 // may need to remove disabled child packages on the system partition 7848 // or may need to not add child packages if the parent apk is updated 7849 // on the data partition and no longer defines this child package. 7850 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7851 // If this is a parent package for an updated system app and this system 7852 // app got an OTA update which no longer defines some of the child packages 7853 // we have to prune them from the disabled system packages. 7854 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 7855 if (disabledPs != null) { 7856 final int scannedChildCount = (pkg.childPackages != null) 7857 ? pkg.childPackages.size() : 0; 7858 final int disabledChildCount = disabledPs.childPackageNames != null 7859 ? disabledPs.childPackageNames.size() : 0; 7860 for (int i = 0; i < disabledChildCount; i++) { 7861 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 7862 boolean disabledPackageAvailable = false; 7863 for (int j = 0; j < scannedChildCount; j++) { 7864 PackageParser.Package childPkg = pkg.childPackages.get(j); 7865 if (childPkg.packageName.equals(disabledChildPackageName)) { 7866 disabledPackageAvailable = true; 7867 break; 7868 } 7869 } 7870 if (!disabledPackageAvailable) { 7871 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 7872 } 7873 } 7874 } 7875 } 7876 } 7877 7878 boolean updatedPkgBetter = false; 7879 // First check if this is a system package that may involve an update 7880 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7881 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 7882 // it needs to drop FLAG_PRIVILEGED. 7883 if (locationIsPrivileged(scanFile)) { 7884 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7885 } else { 7886 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7887 } 7888 7889 if (ps != null && !ps.codePath.equals(scanFile)) { 7890 // The path has changed from what was last scanned... check the 7891 // version of the new path against what we have stored to determine 7892 // what to do. 7893 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 7894 if (pkg.mVersionCode <= ps.versionCode) { 7895 // The system package has been updated and the code path does not match 7896 // Ignore entry. Skip it. 7897 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 7898 + " ignored: updated version " + ps.versionCode 7899 + " better than this " + pkg.mVersionCode); 7900 if (!updatedPkg.codePath.equals(scanFile)) { 7901 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 7902 + ps.name + " changing from " + updatedPkg.codePathString 7903 + " to " + scanFile); 7904 updatedPkg.codePath = scanFile; 7905 updatedPkg.codePathString = scanFile.toString(); 7906 updatedPkg.resourcePath = scanFile; 7907 updatedPkg.resourcePathString = scanFile.toString(); 7908 } 7909 updatedPkg.pkg = pkg; 7910 updatedPkg.versionCode = pkg.mVersionCode; 7911 7912 // Update the disabled system child packages to point to the package too. 7913 final int childCount = updatedPkg.childPackageNames != null 7914 ? updatedPkg.childPackageNames.size() : 0; 7915 for (int i = 0; i < childCount; i++) { 7916 String childPackageName = updatedPkg.childPackageNames.get(i); 7917 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 7918 childPackageName); 7919 if (updatedChildPkg != null) { 7920 updatedChildPkg.pkg = pkg; 7921 updatedChildPkg.versionCode = pkg.mVersionCode; 7922 } 7923 } 7924 7925 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 7926 + scanFile + " ignored: updated version " + ps.versionCode 7927 + " better than this " + pkg.mVersionCode); 7928 } else { 7929 // The current app on the system partition is better than 7930 // what we have updated to on the data partition; switch 7931 // back to the system partition version. 7932 // At this point, its safely assumed that package installation for 7933 // apps in system partition will go through. If not there won't be a working 7934 // version of the app 7935 // writer 7936 synchronized (mPackages) { 7937 // Just remove the loaded entries from package lists. 7938 mPackages.remove(ps.name); 7939 } 7940 7941 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7942 + " reverting from " + ps.codePathString 7943 + ": new version " + pkg.mVersionCode 7944 + " better than installed " + ps.versionCode); 7945 7946 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7947 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7948 synchronized (mInstallLock) { 7949 args.cleanUpResourcesLI(); 7950 } 7951 synchronized (mPackages) { 7952 mSettings.enableSystemPackageLPw(ps.name); 7953 } 7954 updatedPkgBetter = true; 7955 } 7956 } 7957 } 7958 7959 if (updatedPkg != null) { 7960 // An updated system app will not have the PARSE_IS_SYSTEM flag set 7961 // initially 7962 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 7963 7964 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 7965 // flag set initially 7966 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 7967 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 7968 } 7969 } 7970 7971 // Verify certificates against what was last scanned 7972 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 7973 7974 /* 7975 * A new system app appeared, but we already had a non-system one of the 7976 * same name installed earlier. 7977 */ 7978 boolean shouldHideSystemApp = false; 7979 if (updatedPkg == null && ps != null 7980 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 7981 /* 7982 * Check to make sure the signatures match first. If they don't, 7983 * wipe the installed application and its data. 7984 */ 7985 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 7986 != PackageManager.SIGNATURE_MATCH) { 7987 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 7988 + " signatures don't match existing userdata copy; removing"); 7989 try (PackageFreezer freezer = freezePackage(pkg.packageName, 7990 "scanPackageInternalLI")) { 7991 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 7992 } 7993 ps = null; 7994 } else { 7995 /* 7996 * If the newly-added system app is an older version than the 7997 * already installed version, hide it. It will be scanned later 7998 * and re-added like an update. 7999 */ 8000 if (pkg.mVersionCode <= ps.versionCode) { 8001 shouldHideSystemApp = true; 8002 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 8003 + " but new version " + pkg.mVersionCode + " better than installed " 8004 + ps.versionCode + "; hiding system"); 8005 } else { 8006 /* 8007 * The newly found system app is a newer version that the 8008 * one previously installed. Simply remove the 8009 * already-installed application and replace it with our own 8010 * while keeping the application data. 8011 */ 8012 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 8013 + " reverting from " + ps.codePathString + ": new version " 8014 + pkg.mVersionCode + " better than installed " + ps.versionCode); 8015 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 8016 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 8017 synchronized (mInstallLock) { 8018 args.cleanUpResourcesLI(); 8019 } 8020 } 8021 } 8022 } 8023 8024 // The apk is forward locked (not public) if its code and resources 8025 // are kept in different files. (except for app in either system or 8026 // vendor path). 8027 // TODO grab this value from PackageSettings 8028 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8029 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 8030 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 8031 } 8032 } 8033 8034 // TODO: extend to support forward-locked splits 8035 String resourcePath = null; 8036 String baseResourcePath = null; 8037 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 8038 if (ps != null && ps.resourcePathString != null) { 8039 resourcePath = ps.resourcePathString; 8040 baseResourcePath = ps.resourcePathString; 8041 } else { 8042 // Should not happen at all. Just log an error. 8043 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 8044 } 8045 } else { 8046 resourcePath = pkg.codePath; 8047 baseResourcePath = pkg.baseCodePath; 8048 } 8049 8050 // Set application objects path explicitly. 8051 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 8052 pkg.setApplicationInfoCodePath(pkg.codePath); 8053 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 8054 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 8055 pkg.setApplicationInfoResourcePath(resourcePath); 8056 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 8057 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 8058 8059 final int userId = ((user == null) ? 0 : user.getIdentifier()); 8060 if (ps != null && ps.getInstantApp(userId)) { 8061 scanFlags |= SCAN_AS_INSTANT_APP; 8062 } 8063 8064 // Note that we invoke the following method only if we are about to unpack an application 8065 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 8066 | SCAN_UPDATE_SIGNATURE, currentTime, user); 8067 8068 /* 8069 * If the system app should be overridden by a previously installed 8070 * data, hide the system app now and let the /data/app scan pick it up 8071 * again. 8072 */ 8073 if (shouldHideSystemApp) { 8074 synchronized (mPackages) { 8075 mSettings.disableSystemPackageLPw(pkg.packageName, true); 8076 } 8077 } 8078 8079 return scannedPkg; 8080 } 8081 8082 private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) { 8083 // Derive the new package synthetic package name 8084 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER 8085 + pkg.staticSharedLibVersion); 8086 } 8087 8088 private static String fixProcessName(String defProcessName, 8089 String processName) { 8090 if (processName == null) { 8091 return defProcessName; 8092 } 8093 return processName; 8094 } 8095 8096 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 8097 throws PackageManagerException { 8098 if (pkgSetting.signatures.mSignatures != null) { 8099 // Already existing package. Make sure signatures match 8100 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 8101 == PackageManager.SIGNATURE_MATCH; 8102 if (!match) { 8103 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 8104 == PackageManager.SIGNATURE_MATCH; 8105 } 8106 if (!match) { 8107 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 8108 == PackageManager.SIGNATURE_MATCH; 8109 } 8110 if (!match) { 8111 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 8112 + pkg.packageName + " signatures do not match the " 8113 + "previously installed version; ignoring!"); 8114 } 8115 } 8116 8117 // Check for shared user signatures 8118 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 8119 // Already existing package. Make sure signatures match 8120 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8121 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 8122 if (!match) { 8123 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 8124 == PackageManager.SIGNATURE_MATCH; 8125 } 8126 if (!match) { 8127 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 8128 == PackageManager.SIGNATURE_MATCH; 8129 } 8130 if (!match) { 8131 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 8132 "Package " + pkg.packageName 8133 + " has no signatures that match those in shared user " 8134 + pkgSetting.sharedUser.name + "; ignoring!"); 8135 } 8136 } 8137 } 8138 8139 /** 8140 * Enforces that only the system UID or root's UID can call a method exposed 8141 * via Binder. 8142 * 8143 * @param message used as message if SecurityException is thrown 8144 * @throws SecurityException if the caller is not system or root 8145 */ 8146 private static final void enforceSystemOrRoot(String message) { 8147 final int uid = Binder.getCallingUid(); 8148 if (uid != Process.SYSTEM_UID && uid != 0) { 8149 throw new SecurityException(message); 8150 } 8151 } 8152 8153 @Override 8154 public void performFstrimIfNeeded() { 8155 enforceSystemOrRoot("Only the system can request fstrim"); 8156 8157 // Before everything else, see whether we need to fstrim. 8158 try { 8159 IStorageManager sm = PackageHelper.getStorageManager(); 8160 if (sm != null) { 8161 boolean doTrim = false; 8162 final long interval = android.provider.Settings.Global.getLong( 8163 mContext.getContentResolver(), 8164 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 8165 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 8166 if (interval > 0) { 8167 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance(); 8168 if (timeSinceLast > interval) { 8169 doTrim = true; 8170 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 8171 + "; running immediately"); 8172 } 8173 } 8174 if (doTrim) { 8175 final boolean dexOptDialogShown; 8176 synchronized (mPackages) { 8177 dexOptDialogShown = mDexOptDialogShown; 8178 } 8179 if (!isFirstBoot() && dexOptDialogShown) { 8180 try { 8181 ActivityManager.getService().showBootMessage( 8182 mContext.getResources().getString( 8183 R.string.android_upgrading_fstrim), true); 8184 } catch (RemoteException e) { 8185 } 8186 } 8187 sm.runMaintenance(); 8188 } 8189 } else { 8190 Slog.e(TAG, "storageManager service unavailable!"); 8191 } 8192 } catch (RemoteException e) { 8193 // Can't happen; StorageManagerService is local 8194 } 8195 } 8196 8197 @Override 8198 public void updatePackagesIfNeeded() { 8199 enforceSystemOrRoot("Only the system can request package update"); 8200 8201 // We need to re-extract after an OTA. 8202 boolean causeUpgrade = isUpgrade(); 8203 8204 // First boot or factory reset. 8205 // Note: we also handle devices that are upgrading to N right now as if it is their 8206 // first boot, as they do not have profile data. 8207 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 8208 8209 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 8210 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 8211 8212 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 8213 return; 8214 } 8215 8216 List<PackageParser.Package> pkgs; 8217 synchronized (mPackages) { 8218 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 8219 } 8220 8221 final long startTime = System.nanoTime(); 8222 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 8223 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 8224 8225 final int elapsedTimeSeconds = 8226 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 8227 8228 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 8229 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 8230 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 8231 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 8232 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 8233 } 8234 8235 /** 8236 * Performs dexopt on the set of packages in {@code packages} and returns an int array 8237 * containing statistics about the invocation. The array consists of three elements, 8238 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 8239 * and {@code numberOfPackagesFailed}. 8240 */ 8241 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 8242 String compilerFilter) { 8243 8244 int numberOfPackagesVisited = 0; 8245 int numberOfPackagesOptimized = 0; 8246 int numberOfPackagesSkipped = 0; 8247 int numberOfPackagesFailed = 0; 8248 final int numberOfPackagesToDexopt = pkgs.size(); 8249 8250 for (PackageParser.Package pkg : pkgs) { 8251 numberOfPackagesVisited++; 8252 8253 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 8254 if (DEBUG_DEXOPT) { 8255 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 8256 } 8257 numberOfPackagesSkipped++; 8258 continue; 8259 } 8260 8261 if (DEBUG_DEXOPT) { 8262 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 8263 numberOfPackagesToDexopt + ": " + pkg.packageName); 8264 } 8265 8266 if (showDialog) { 8267 try { 8268 ActivityManager.getService().showBootMessage( 8269 mContext.getResources().getString(R.string.android_upgrading_apk, 8270 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 8271 } catch (RemoteException e) { 8272 } 8273 synchronized (mPackages) { 8274 mDexOptDialogShown = true; 8275 } 8276 } 8277 8278 // If the OTA updates a system app which was previously preopted to a non-preopted state 8279 // the app might end up being verified at runtime. That's because by default the apps 8280 // are verify-profile but for preopted apps there's no profile. 8281 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 8282 // that before the OTA the app was preopted) the app gets compiled with a non-profile 8283 // filter (by default interpret-only). 8284 // Note that at this stage unused apps are already filtered. 8285 if (isSystemApp(pkg) && 8286 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 8287 !Environment.getReferenceProfile(pkg.packageName).exists()) { 8288 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 8289 } 8290 8291 // checkProfiles is false to avoid merging profiles during boot which 8292 // might interfere with background compilation (b/28612421). 8293 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 8294 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 8295 // trade-off worth doing to save boot time work. 8296 int dexOptStatus = performDexOptTraced(pkg.packageName, 8297 false /* checkProfiles */, 8298 compilerFilter, 8299 false /* force */); 8300 switch (dexOptStatus) { 8301 case PackageDexOptimizer.DEX_OPT_PERFORMED: 8302 numberOfPackagesOptimized++; 8303 break; 8304 case PackageDexOptimizer.DEX_OPT_SKIPPED: 8305 numberOfPackagesSkipped++; 8306 break; 8307 case PackageDexOptimizer.DEX_OPT_FAILED: 8308 numberOfPackagesFailed++; 8309 break; 8310 default: 8311 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 8312 break; 8313 } 8314 } 8315 8316 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 8317 numberOfPackagesFailed }; 8318 } 8319 8320 @Override 8321 public void notifyPackageUse(String packageName, int reason) { 8322 synchronized (mPackages) { 8323 PackageParser.Package p = mPackages.get(packageName); 8324 if (p == null) { 8325 return; 8326 } 8327 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 8328 } 8329 } 8330 8331 @Override 8332 public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) { 8333 int userId = UserHandle.getCallingUserId(); 8334 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId); 8335 if (ai == null) { 8336 Slog.w(TAG, "Loading a package that does not exist for the calling user. package=" 8337 + loadingPackageName + ", user=" + userId); 8338 return; 8339 } 8340 mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId); 8341 } 8342 8343 // TODO: this is not used nor needed. Delete it. 8344 @Override 8345 public boolean performDexOptIfNeeded(String packageName) { 8346 int dexOptStatus = performDexOptTraced(packageName, 8347 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 8348 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8349 } 8350 8351 @Override 8352 public boolean performDexOpt(String packageName, 8353 boolean checkProfiles, int compileReason, boolean force) { 8354 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 8355 getCompilerFilterForReason(compileReason), force); 8356 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8357 } 8358 8359 @Override 8360 public boolean performDexOptMode(String packageName, 8361 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8362 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 8363 targetCompilerFilter, force); 8364 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8365 } 8366 8367 private int performDexOptTraced(String packageName, 8368 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8369 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 8370 try { 8371 return performDexOptInternal(packageName, checkProfiles, 8372 targetCompilerFilter, force); 8373 } finally { 8374 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8375 } 8376 } 8377 8378 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 8379 // if the package can now be considered up to date for the given filter. 8380 private int performDexOptInternal(String packageName, 8381 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8382 PackageParser.Package p; 8383 synchronized (mPackages) { 8384 p = mPackages.get(packageName); 8385 if (p == null) { 8386 // Package could not be found. Report failure. 8387 return PackageDexOptimizer.DEX_OPT_FAILED; 8388 } 8389 mPackageUsage.maybeWriteAsync(mPackages); 8390 mCompilerStats.maybeWriteAsync(); 8391 } 8392 long callingId = Binder.clearCallingIdentity(); 8393 try { 8394 synchronized (mInstallLock) { 8395 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 8396 targetCompilerFilter, force); 8397 } 8398 } finally { 8399 Binder.restoreCallingIdentity(callingId); 8400 } 8401 } 8402 8403 public ArraySet<String> getOptimizablePackages() { 8404 ArraySet<String> pkgs = new ArraySet<String>(); 8405 synchronized (mPackages) { 8406 for (PackageParser.Package p : mPackages.values()) { 8407 if (PackageDexOptimizer.canOptimizePackage(p)) { 8408 pkgs.add(p.packageName); 8409 } 8410 } 8411 } 8412 return pkgs; 8413 } 8414 8415 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 8416 boolean checkProfiles, String targetCompilerFilter, 8417 boolean force) { 8418 // Select the dex optimizer based on the force parameter. 8419 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 8420 // allocate an object here. 8421 PackageDexOptimizer pdo = force 8422 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 8423 : mPackageDexOptimizer; 8424 8425 // Optimize all dependencies first. Note: we ignore the return value and march on 8426 // on errors. 8427 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 8428 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 8429 if (!deps.isEmpty()) { 8430 for (PackageParser.Package depPackage : deps) { 8431 // TODO: Analyze and investigate if we (should) profile libraries. 8432 // Currently this will do a full compilation of the library by default. 8433 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 8434 false /* checkProfiles */, 8435 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 8436 getOrCreateCompilerPackageStats(depPackage), 8437 mDexManager.isUsedByOtherApps(p.packageName)); 8438 } 8439 } 8440 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 8441 targetCompilerFilter, getOrCreateCompilerPackageStats(p), 8442 mDexManager.isUsedByOtherApps(p.packageName)); 8443 } 8444 8445 // Performs dexopt on the used secondary dex files belonging to the given package. 8446 // Returns true if all dex files were process successfully (which could mean either dexopt or 8447 // skip). Returns false if any of the files caused errors. 8448 @Override 8449 public boolean performDexOptSecondary(String packageName, String compilerFilter, 8450 boolean force) { 8451 return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); 8452 } 8453 8454 /** 8455 * Reconcile the information we have about the secondary dex files belonging to 8456 * {@code packagName} and the actual dex files. For all dex files that were 8457 * deleted, update the internal records and delete the generated oat files. 8458 */ 8459 @Override 8460 public void reconcileSecondaryDexFiles(String packageName) { 8461 mDexManager.reconcileSecondaryDexFiles(packageName); 8462 } 8463 8464 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject 8465 // a reference there. 8466 /*package*/ DexManager getDexManager() { 8467 return mDexManager; 8468 } 8469 8470 /** 8471 * Execute the background dexopt job immediately. 8472 */ 8473 @Override 8474 public boolean runBackgroundDexoptJob() { 8475 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext); 8476 } 8477 8478 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 8479 if (p.usesLibraries != null || p.usesOptionalLibraries != null 8480 || p.usesStaticLibraries != null) { 8481 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 8482 Set<String> collectedNames = new HashSet<>(); 8483 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 8484 8485 retValue.remove(p); 8486 8487 return retValue; 8488 } else { 8489 return Collections.emptyList(); 8490 } 8491 } 8492 8493 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 8494 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) { 8495 if (!collectedNames.contains(p.packageName)) { 8496 collectedNames.add(p.packageName); 8497 collected.add(p); 8498 8499 if (p.usesLibraries != null) { 8500 findSharedNonSystemLibrariesRecursive(p.usesLibraries, 8501 null, collected, collectedNames); 8502 } 8503 if (p.usesOptionalLibraries != null) { 8504 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, 8505 null, collected, collectedNames); 8506 } 8507 if (p.usesStaticLibraries != null) { 8508 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries, 8509 p.usesStaticLibrariesVersions, collected, collectedNames); 8510 } 8511 } 8512 } 8513 8514 private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions, 8515 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) { 8516 final int libNameCount = libs.size(); 8517 for (int i = 0; i < libNameCount; i++) { 8518 String libName = libs.get(i); 8519 int version = (versions != null && versions.length == libNameCount) 8520 ? versions[i] : PackageManager.VERSION_CODE_HIGHEST; 8521 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version); 8522 if (libPkg != null) { 8523 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 8524 } 8525 } 8526 } 8527 8528 private PackageParser.Package findSharedNonSystemLibrary(String name, int version) { 8529 synchronized (mPackages) { 8530 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version); 8531 if (libEntry != null) { 8532 return mPackages.get(libEntry.apk); 8533 } 8534 return null; 8535 } 8536 } 8537 8538 private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) { 8539 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 8540 if (versionedLib == null) { 8541 return null; 8542 } 8543 return versionedLib.get(version); 8544 } 8545 8546 private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) { 8547 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get( 8548 pkg.staticSharedLibName); 8549 if (versionedLib == null) { 8550 return null; 8551 } 8552 int previousLibVersion = -1; 8553 final int versionCount = versionedLib.size(); 8554 for (int i = 0; i < versionCount; i++) { 8555 final int libVersion = versionedLib.keyAt(i); 8556 if (libVersion < pkg.staticSharedLibVersion) { 8557 previousLibVersion = Math.max(previousLibVersion, libVersion); 8558 } 8559 } 8560 if (previousLibVersion >= 0) { 8561 return versionedLib.get(previousLibVersion); 8562 } 8563 return null; 8564 } 8565 8566 public void shutdown() { 8567 mPackageUsage.writeNow(mPackages); 8568 mCompilerStats.writeNow(); 8569 } 8570 8571 @Override 8572 public void dumpProfiles(String packageName) { 8573 PackageParser.Package pkg; 8574 synchronized (mPackages) { 8575 pkg = mPackages.get(packageName); 8576 if (pkg == null) { 8577 throw new IllegalArgumentException("Unknown package: " + packageName); 8578 } 8579 } 8580 /* Only the shell, root, or the app user should be able to dump profiles. */ 8581 int callingUid = Binder.getCallingUid(); 8582 if (callingUid != Process.SHELL_UID && 8583 callingUid != Process.ROOT_UID && 8584 callingUid != pkg.applicationInfo.uid) { 8585 throw new SecurityException("dumpProfiles"); 8586 } 8587 8588 synchronized (mInstallLock) { 8589 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 8590 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 8591 try { 8592 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 8593 String codePaths = TextUtils.join(";", allCodePaths); 8594 mInstaller.dumpProfiles(sharedGid, packageName, codePaths); 8595 } catch (InstallerException e) { 8596 Slog.w(TAG, "Failed to dump profiles", e); 8597 } 8598 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8599 } 8600 } 8601 8602 @Override 8603 public void forceDexOpt(String packageName) { 8604 enforceSystemOrRoot("forceDexOpt"); 8605 8606 PackageParser.Package pkg; 8607 synchronized (mPackages) { 8608 pkg = mPackages.get(packageName); 8609 if (pkg == null) { 8610 throw new IllegalArgumentException("Unknown package: " + packageName); 8611 } 8612 } 8613 8614 synchronized (mInstallLock) { 8615 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 8616 8617 // Whoever is calling forceDexOpt wants a fully compiled package. 8618 // Don't use profiles since that may cause compilation to be skipped. 8619 final int res = performDexOptInternalWithDependenciesLI(pkg, 8620 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 8621 true /* force */); 8622 8623 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8624 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 8625 throw new IllegalStateException("Failed to dexopt: " + res); 8626 } 8627 } 8628 } 8629 8630 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 8631 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8632 Slog.w(TAG, "Unable to update from " + oldPkg.name 8633 + " to " + newPkg.packageName 8634 + ": old package not in system partition"); 8635 return false; 8636 } else if (mPackages.get(oldPkg.name) != null) { 8637 Slog.w(TAG, "Unable to update from " + oldPkg.name 8638 + " to " + newPkg.packageName 8639 + ": old package still exists"); 8640 return false; 8641 } 8642 return true; 8643 } 8644 8645 void removeCodePathLI(File codePath) { 8646 if (codePath.isDirectory()) { 8647 try { 8648 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 8649 } catch (InstallerException e) { 8650 Slog.w(TAG, "Failed to remove code path", e); 8651 } 8652 } else { 8653 codePath.delete(); 8654 } 8655 } 8656 8657 private int[] resolveUserIds(int userId) { 8658 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 8659 } 8660 8661 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 8662 if (pkg == null) { 8663 Slog.wtf(TAG, "Package was null!", new Throwable()); 8664 return; 8665 } 8666 clearAppDataLeafLIF(pkg, userId, flags); 8667 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8668 for (int i = 0; i < childCount; i++) { 8669 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 8670 } 8671 } 8672 8673 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 8674 final PackageSetting ps; 8675 synchronized (mPackages) { 8676 ps = mSettings.mPackages.get(pkg.packageName); 8677 } 8678 for (int realUserId : resolveUserIds(userId)) { 8679 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 8680 try { 8681 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 8682 ceDataInode); 8683 } catch (InstallerException e) { 8684 Slog.w(TAG, String.valueOf(e)); 8685 } 8686 } 8687 } 8688 8689 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 8690 if (pkg == null) { 8691 Slog.wtf(TAG, "Package was null!", new Throwable()); 8692 return; 8693 } 8694 destroyAppDataLeafLIF(pkg, userId, flags); 8695 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8696 for (int i = 0; i < childCount; i++) { 8697 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 8698 } 8699 } 8700 8701 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 8702 final PackageSetting ps; 8703 synchronized (mPackages) { 8704 ps = mSettings.mPackages.get(pkg.packageName); 8705 } 8706 for (int realUserId : resolveUserIds(userId)) { 8707 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 8708 try { 8709 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 8710 ceDataInode); 8711 } catch (InstallerException e) { 8712 Slog.w(TAG, String.valueOf(e)); 8713 } 8714 mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId); 8715 } 8716 } 8717 8718 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 8719 if (pkg == null) { 8720 Slog.wtf(TAG, "Package was null!", new Throwable()); 8721 return; 8722 } 8723 destroyAppProfilesLeafLIF(pkg); 8724 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8725 for (int i = 0; i < childCount; i++) { 8726 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 8727 } 8728 } 8729 8730 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 8731 try { 8732 mInstaller.destroyAppProfiles(pkg.packageName); 8733 } catch (InstallerException e) { 8734 Slog.w(TAG, String.valueOf(e)); 8735 } 8736 } 8737 8738 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 8739 if (pkg == null) { 8740 Slog.wtf(TAG, "Package was null!", new Throwable()); 8741 return; 8742 } 8743 clearAppProfilesLeafLIF(pkg); 8744 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8745 for (int i = 0; i < childCount; i++) { 8746 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 8747 } 8748 } 8749 8750 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 8751 try { 8752 mInstaller.clearAppProfiles(pkg.packageName); 8753 } catch (InstallerException e) { 8754 Slog.w(TAG, String.valueOf(e)); 8755 } 8756 } 8757 8758 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 8759 long lastUpdateTime) { 8760 // Set parent install/update time 8761 PackageSetting ps = (PackageSetting) pkg.mExtras; 8762 if (ps != null) { 8763 ps.firstInstallTime = firstInstallTime; 8764 ps.lastUpdateTime = lastUpdateTime; 8765 } 8766 // Set children install/update time 8767 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8768 for (int i = 0; i < childCount; i++) { 8769 PackageParser.Package childPkg = pkg.childPackages.get(i); 8770 ps = (PackageSetting) childPkg.mExtras; 8771 if (ps != null) { 8772 ps.firstInstallTime = firstInstallTime; 8773 ps.lastUpdateTime = lastUpdateTime; 8774 } 8775 } 8776 } 8777 8778 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 8779 PackageParser.Package changingLib) { 8780 if (file.path != null) { 8781 usesLibraryFiles.add(file.path); 8782 return; 8783 } 8784 PackageParser.Package p = mPackages.get(file.apk); 8785 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 8786 // If we are doing this while in the middle of updating a library apk, 8787 // then we need to make sure to use that new apk for determining the 8788 // dependencies here. (We haven't yet finished committing the new apk 8789 // to the package manager state.) 8790 if (p == null || p.packageName.equals(changingLib.packageName)) { 8791 p = changingLib; 8792 } 8793 } 8794 if (p != null) { 8795 usesLibraryFiles.addAll(p.getAllCodePaths()); 8796 } 8797 } 8798 8799 private void updateSharedLibrariesLPr(PackageParser.Package pkg, 8800 PackageParser.Package changingLib) throws PackageManagerException { 8801 if (pkg == null) { 8802 return; 8803 } 8804 ArraySet<String> usesLibraryFiles = null; 8805 if (pkg.usesLibraries != null) { 8806 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries, 8807 null, null, pkg.packageName, changingLib, true, null); 8808 } 8809 if (pkg.usesStaticLibraries != null) { 8810 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries, 8811 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests, 8812 pkg.packageName, changingLib, true, usesLibraryFiles); 8813 } 8814 if (pkg.usesOptionalLibraries != null) { 8815 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries, 8816 null, null, pkg.packageName, changingLib, false, usesLibraryFiles); 8817 } 8818 if (!ArrayUtils.isEmpty(usesLibraryFiles)) { 8819 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]); 8820 } else { 8821 pkg.usesLibraryFiles = null; 8822 } 8823 } 8824 8825 private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries, 8826 @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests, 8827 @NonNull String packageName, @Nullable PackageParser.Package changingLib, 8828 boolean required, @Nullable ArraySet<String> outUsedLibraries) 8829 throws PackageManagerException { 8830 final int libCount = requestedLibraries.size(); 8831 for (int i = 0; i < libCount; i++) { 8832 final String libName = requestedLibraries.get(i); 8833 final int libVersion = requiredVersions != null ? requiredVersions[i] 8834 : SharedLibraryInfo.VERSION_UNDEFINED; 8835 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion); 8836 if (libEntry == null) { 8837 if (required) { 8838 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8839 "Package " + packageName + " requires unavailable shared library " 8840 + libName + "; failing!"); 8841 } else { 8842 Slog.w(TAG, "Package " + packageName 8843 + " desires unavailable shared library " 8844 + libName + "; ignoring!"); 8845 } 8846 } else { 8847 if (requiredVersions != null && requiredCertDigests != null) { 8848 if (libEntry.info.getVersion() != requiredVersions[i]) { 8849 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8850 "Package " + packageName + " requires unavailable static shared" 8851 + " library " + libName + " version " 8852 + libEntry.info.getVersion() + "; failing!"); 8853 } 8854 8855 PackageParser.Package libPkg = mPackages.get(libEntry.apk); 8856 if (libPkg == null) { 8857 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8858 "Package " + packageName + " requires unavailable static shared" 8859 + " library; failing!"); 8860 } 8861 8862 String expectedCertDigest = requiredCertDigests[i]; 8863 String libCertDigest = PackageUtils.computeCertSha256Digest( 8864 libPkg.mSignatures[0]); 8865 if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) { 8866 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8867 "Package " + packageName + " requires differently signed" + 8868 " static shared library; failing!"); 8869 } 8870 } 8871 8872 if (outUsedLibraries == null) { 8873 outUsedLibraries = new ArraySet<>(); 8874 } 8875 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib); 8876 } 8877 } 8878 return outUsedLibraries; 8879 } 8880 8881 private static boolean hasString(List<String> list, List<String> which) { 8882 if (list == null) { 8883 return false; 8884 } 8885 for (int i=list.size()-1; i>=0; i--) { 8886 for (int j=which.size()-1; j>=0; j--) { 8887 if (which.get(j).equals(list.get(i))) { 8888 return true; 8889 } 8890 } 8891 } 8892 return false; 8893 } 8894 8895 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 8896 PackageParser.Package changingPkg) { 8897 ArrayList<PackageParser.Package> res = null; 8898 for (PackageParser.Package pkg : mPackages.values()) { 8899 if (changingPkg != null 8900 && !hasString(pkg.usesLibraries, changingPkg.libraryNames) 8901 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames) 8902 && !ArrayUtils.contains(pkg.usesStaticLibraries, 8903 changingPkg.staticSharedLibName)) { 8904 return null; 8905 } 8906 if (res == null) { 8907 res = new ArrayList<>(); 8908 } 8909 res.add(pkg); 8910 try { 8911 updateSharedLibrariesLPr(pkg, changingPkg); 8912 } catch (PackageManagerException e) { 8913 // If a system app update or an app and a required lib missing we 8914 // delete the package and for updated system apps keep the data as 8915 // it is better for the user to reinstall than to be in an limbo 8916 // state. Also libs disappearing under an app should never happen 8917 // - just in case. 8918 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) { 8919 final int flags = pkg.isUpdatedSystemApp() 8920 ? PackageManager.DELETE_KEEP_DATA : 0; 8921 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(), 8922 flags , null, true, null); 8923 } 8924 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 8925 } 8926 } 8927 return res; 8928 } 8929 8930 /** 8931 * Derive the value of the {@code cpuAbiOverride} based on the provided 8932 * value and an optional stored value from the package settings. 8933 */ 8934 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 8935 String cpuAbiOverride = null; 8936 8937 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 8938 cpuAbiOverride = null; 8939 } else if (abiOverride != null) { 8940 cpuAbiOverride = abiOverride; 8941 } else if (settings != null) { 8942 cpuAbiOverride = settings.cpuAbiOverrideString; 8943 } 8944 8945 return cpuAbiOverride; 8946 } 8947 8948 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 8949 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 8950 throws PackageManagerException { 8951 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 8952 // If the package has children and this is the first dive in the function 8953 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 8954 // whether all packages (parent and children) would be successfully scanned 8955 // before the actual scan since scanning mutates internal state and we want 8956 // to atomically install the package and its children. 8957 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8958 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 8959 scanFlags |= SCAN_CHECK_ONLY; 8960 } 8961 } else { 8962 scanFlags &= ~SCAN_CHECK_ONLY; 8963 } 8964 8965 final PackageParser.Package scannedPkg; 8966 try { 8967 // Scan the parent 8968 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 8969 // Scan the children 8970 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8971 for (int i = 0; i < childCount; i++) { 8972 PackageParser.Package childPkg = pkg.childPackages.get(i); 8973 scanPackageLI(childPkg, policyFlags, 8974 scanFlags, currentTime, user); 8975 } 8976 } finally { 8977 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8978 } 8979 8980 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8981 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 8982 } 8983 8984 return scannedPkg; 8985 } 8986 8987 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 8988 int scanFlags, long currentTime, @Nullable UserHandle user) 8989 throws PackageManagerException { 8990 boolean success = false; 8991 try { 8992 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 8993 currentTime, user); 8994 success = true; 8995 return res; 8996 } finally { 8997 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 8998 // DELETE_DATA_ON_FAILURES is only used by frozen paths 8999 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 9000 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 9001 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 9002 } 9003 } 9004 } 9005 9006 /** 9007 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 9008 */ 9009 private static boolean apkHasCode(String fileName) { 9010 StrictJarFile jarFile = null; 9011 try { 9012 jarFile = new StrictJarFile(fileName, 9013 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 9014 return jarFile.findEntry("classes.dex") != null; 9015 } catch (IOException ignore) { 9016 } finally { 9017 try { 9018 if (jarFile != null) { 9019 jarFile.close(); 9020 } 9021 } catch (IOException ignore) {} 9022 } 9023 return false; 9024 } 9025 9026 /** 9027 * Enforces code policy for the package. This ensures that if an APK has 9028 * declared hasCode="true" in its manifest that the APK actually contains 9029 * code. 9030 * 9031 * @throws PackageManagerException If bytecode could not be found when it should exist 9032 */ 9033 private static void assertCodePolicy(PackageParser.Package pkg) 9034 throws PackageManagerException { 9035 final boolean shouldHaveCode = 9036 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 9037 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 9038 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 9039 "Package " + pkg.baseCodePath + " code is missing"); 9040 } 9041 9042 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 9043 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 9044 final boolean splitShouldHaveCode = 9045 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 9046 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 9047 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 9048 "Package " + pkg.splitCodePaths[i] + " code is missing"); 9049 } 9050 } 9051 } 9052 } 9053 9054 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 9055 final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user) 9056 throws PackageManagerException { 9057 if (DEBUG_PACKAGE_SCANNING) { 9058 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 9059 Log.d(TAG, "Scanning package " + pkg.packageName); 9060 } 9061 9062 applyPolicy(pkg, policyFlags); 9063 9064 assertPackageIsValid(pkg, policyFlags, scanFlags); 9065 9066 // Initialize package source and resource directories 9067 final File scanFile = new File(pkg.codePath); 9068 final File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 9069 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 9070 9071 SharedUserSetting suid = null; 9072 PackageSetting pkgSetting = null; 9073 9074 // Getting the package setting may have a side-effect, so if we 9075 // are only checking if scan would succeed, stash a copy of the 9076 // old setting to restore at the end. 9077 PackageSetting nonMutatedPs = null; 9078 9079 // We keep references to the derived CPU Abis from settings in oder to reuse 9080 // them in the case where we're not upgrading or booting for the first time. 9081 String primaryCpuAbiFromSettings = null; 9082 String secondaryCpuAbiFromSettings = null; 9083 9084 // writer 9085 synchronized (mPackages) { 9086 if (pkg.mSharedUserId != null) { 9087 // SIDE EFFECTS; may potentially allocate a new shared user 9088 suid = mSettings.getSharedUserLPw( 9089 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); 9090 if (DEBUG_PACKAGE_SCANNING) { 9091 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 9092 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 9093 + "): packages=" + suid.packages); 9094 } 9095 } 9096 9097 // Check if we are renaming from an original package name. 9098 PackageSetting origPackage = null; 9099 String realName = null; 9100 if (pkg.mOriginalPackages != null) { 9101 // This package may need to be renamed to a previously 9102 // installed name. Let's check on that... 9103 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage); 9104 if (pkg.mOriginalPackages.contains(renamed)) { 9105 // This package had originally been installed as the 9106 // original name, and we have already taken care of 9107 // transitioning to the new one. Just update the new 9108 // one to continue using the old name. 9109 realName = pkg.mRealPackage; 9110 if (!pkg.packageName.equals(renamed)) { 9111 // Callers into this function may have already taken 9112 // care of renaming the package; only do it here if 9113 // it is not already done. 9114 pkg.setPackageName(renamed); 9115 } 9116 } else { 9117 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 9118 if ((origPackage = mSettings.getPackageLPr( 9119 pkg.mOriginalPackages.get(i))) != null) { 9120 // We do have the package already installed under its 9121 // original name... should we use it? 9122 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 9123 // New package is not compatible with original. 9124 origPackage = null; 9125 continue; 9126 } else if (origPackage.sharedUser != null) { 9127 // Make sure uid is compatible between packages. 9128 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 9129 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 9130 + " to " + pkg.packageName + ": old uid " 9131 + origPackage.sharedUser.name 9132 + " differs from " + pkg.mSharedUserId); 9133 origPackage = null; 9134 continue; 9135 } 9136 // TODO: Add case when shared user id is added [b/28144775] 9137 } else { 9138 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 9139 + pkg.packageName + " to old name " + origPackage.name); 9140 } 9141 break; 9142 } 9143 } 9144 } 9145 } 9146 9147 if (mTransferedPackages.contains(pkg.packageName)) { 9148 Slog.w(TAG, "Package " + pkg.packageName 9149 + " was transferred to another, but its .apk remains"); 9150 } 9151 9152 // See comments in nonMutatedPs declaration 9153 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 9154 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 9155 if (foundPs != null) { 9156 nonMutatedPs = new PackageSetting(foundPs); 9157 } 9158 } 9159 9160 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) { 9161 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 9162 if (foundPs != null) { 9163 primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString; 9164 secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString; 9165 } 9166 } 9167 9168 pkgSetting = mSettings.getPackageLPr(pkg.packageName); 9169 if (pkgSetting != null && pkgSetting.sharedUser != suid) { 9170 PackageManagerService.reportSettingsProblem(Log.WARN, 9171 "Package " + pkg.packageName + " shared user changed from " 9172 + (pkgSetting.sharedUser != null 9173 ? pkgSetting.sharedUser.name : "<nothing>") 9174 + " to " 9175 + (suid != null ? suid.name : "<nothing>") 9176 + "; replacing with new"); 9177 pkgSetting = null; 9178 } 9179 final PackageSetting oldPkgSetting = 9180 pkgSetting == null ? null : new PackageSetting(pkgSetting); 9181 final PackageSetting disabledPkgSetting = 9182 mSettings.getDisabledSystemPkgLPr(pkg.packageName); 9183 9184 String[] usesStaticLibraries = null; 9185 if (pkg.usesStaticLibraries != null) { 9186 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()]; 9187 pkg.usesStaticLibraries.toArray(usesStaticLibraries); 9188 } 9189 9190 if (pkgSetting == null) { 9191 final String parentPackageName = (pkg.parentPackage != null) 9192 ? pkg.parentPackage.packageName : null; 9193 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 9194 // REMOVE SharedUserSetting from method; update in a separate call 9195 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage, 9196 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile, 9197 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi, 9198 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode, 9199 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user, 9200 true /*allowInstall*/, instantApp, parentPackageName, 9201 pkg.getChildPackageNames(), UserManagerService.getInstance(), 9202 usesStaticLibraries, pkg.usesStaticLibrariesVersions); 9203 // SIDE EFFECTS; updates system state; move elsewhere 9204 if (origPackage != null) { 9205 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name); 9206 } 9207 mSettings.addUserToSettingLPw(pkgSetting); 9208 } else { 9209 // REMOVE SharedUserSetting from method; update in a separate call. 9210 // 9211 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi, 9212 // secondaryCpuAbi are not known at this point so we always update them 9213 // to null here, only to reset them at a later point. 9214 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile, 9215 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi, 9216 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags, 9217 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(), 9218 UserManagerService.getInstance(), usesStaticLibraries, 9219 pkg.usesStaticLibrariesVersions); 9220 } 9221 // SIDE EFFECTS; persists system state to files on disk; move elsewhere 9222 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); 9223 9224 // SIDE EFFECTS; modifies system state; move elsewhere 9225 if (pkgSetting.origPackage != null) { 9226 // If we are first transitioning from an original package, 9227 // fix up the new package's name now. We need to do this after 9228 // looking up the package under its new name, so getPackageLP 9229 // can take care of fiddling things correctly. 9230 pkg.setPackageName(origPackage.name); 9231 9232 // File a report about this. 9233 String msg = "New package " + pkgSetting.realName 9234 + " renamed to replace old package " + pkgSetting.name; 9235 reportSettingsProblem(Log.WARN, msg); 9236 9237 // Make a note of it. 9238 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 9239 mTransferedPackages.add(origPackage.name); 9240 } 9241 9242 // No longer need to retain this. 9243 pkgSetting.origPackage = null; 9244 } 9245 9246 // SIDE EFFECTS; modifies system state; move elsewhere 9247 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 9248 // Make a note of it. 9249 mTransferedPackages.add(pkg.packageName); 9250 } 9251 9252 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 9253 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 9254 } 9255 9256 if ((scanFlags & SCAN_BOOTING) == 0 9257 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9258 // Check all shared libraries and map to their actual file path. 9259 // We only do this here for apps not on a system dir, because those 9260 // are the only ones that can fail an install due to this. We 9261 // will take care of the system apps by updating all of their 9262 // library paths after the scan is done. Also during the initial 9263 // scan don't update any libs as we do this wholesale after all 9264 // apps are scanned to avoid dependency based scanning. 9265 updateSharedLibrariesLPr(pkg, null); 9266 } 9267 9268 if (mFoundPolicyFile) { 9269 SELinuxMMAC.assignSeInfoValue(pkg); 9270 } 9271 pkg.applicationInfo.uid = pkgSetting.appId; 9272 pkg.mExtras = pkgSetting; 9273 9274 9275 // Static shared libs have same package with different versions where 9276 // we internally use a synthetic package name to allow multiple versions 9277 // of the same package, therefore we need to compare signatures against 9278 // the package setting for the latest library version. 9279 PackageSetting signatureCheckPs = pkgSetting; 9280 if (pkg.applicationInfo.isStaticSharedLibrary()) { 9281 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg); 9282 if (libraryEntry != null) { 9283 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk); 9284 } 9285 } 9286 9287 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) { 9288 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) { 9289 // We just determined the app is signed correctly, so bring 9290 // over the latest parsed certs. 9291 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9292 } else { 9293 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9294 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 9295 "Package " + pkg.packageName + " upgrade keys do not match the " 9296 + "previously installed version"); 9297 } else { 9298 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9299 String msg = "System package " + pkg.packageName 9300 + " signature changed; retaining data."; 9301 reportSettingsProblem(Log.WARN, msg); 9302 } 9303 } 9304 } else { 9305 try { 9306 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService 9307 verifySignaturesLP(signatureCheckPs, pkg); 9308 // We just determined the app is signed correctly, so bring 9309 // over the latest parsed certs. 9310 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9311 } catch (PackageManagerException e) { 9312 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9313 throw e; 9314 } 9315 // The signature has changed, but this package is in the system 9316 // image... let's recover! 9317 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9318 // However... if this package is part of a shared user, but it 9319 // doesn't match the signature of the shared user, let's fail. 9320 // What this means is that you can't change the signatures 9321 // associated with an overall shared user, which doesn't seem all 9322 // that unreasonable. 9323 if (signatureCheckPs.sharedUser != null) { 9324 if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures, 9325 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 9326 throw new PackageManagerException( 9327 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 9328 "Signature mismatch for shared user: " 9329 + pkgSetting.sharedUser); 9330 } 9331 } 9332 // File a report about this. 9333 String msg = "System package " + pkg.packageName 9334 + " signature changed; retaining data."; 9335 reportSettingsProblem(Log.WARN, msg); 9336 } 9337 } 9338 9339 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 9340 // This package wants to adopt ownership of permissions from 9341 // another package. 9342 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 9343 final String origName = pkg.mAdoptPermissions.get(i); 9344 final PackageSetting orig = mSettings.getPackageLPr(origName); 9345 if (orig != null) { 9346 if (verifyPackageUpdateLPr(orig, pkg)) { 9347 Slog.i(TAG, "Adopting permissions from " + origName + " to " 9348 + pkg.packageName); 9349 // SIDE EFFECTS; updates permissions system state; move elsewhere 9350 mSettings.transferPermissionsLPw(origName, pkg.packageName); 9351 } 9352 } 9353 } 9354 } 9355 } 9356 9357 pkg.applicationInfo.processName = fixProcessName( 9358 pkg.applicationInfo.packageName, 9359 pkg.applicationInfo.processName); 9360 9361 if (pkg != mPlatformPackage) { 9362 // Get all of our default paths setup 9363 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 9364 } 9365 9366 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 9367 9368 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 9369 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) { 9370 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); 9371 derivePackageAbi( 9372 pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir); 9373 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9374 9375 // Some system apps still use directory structure for native libraries 9376 // in which case we might end up not detecting abi solely based on apk 9377 // structure. Try to detect abi based on directory structure. 9378 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 9379 pkg.applicationInfo.primaryCpuAbi == null) { 9380 setBundledAppAbisAndRoots(pkg, pkgSetting); 9381 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9382 } 9383 } else { 9384 // This is not a first boot or an upgrade, don't bother deriving the 9385 // ABI during the scan. Instead, trust the value that was stored in the 9386 // package setting. 9387 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; 9388 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings; 9389 9390 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9391 9392 if (DEBUG_ABI_SELECTION) { 9393 Slog.i(TAG, "Using ABIS and native lib paths from settings : " + 9394 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " + 9395 pkg.applicationInfo.secondaryCpuAbi); 9396 } 9397 } 9398 } else { 9399 if ((scanFlags & SCAN_MOVE) != 0) { 9400 // We haven't run dex-opt for this move (since we've moved the compiled output too) 9401 // but we already have this packages package info in the PackageSetting. We just 9402 // use that and derive the native library path based on the new codepath. 9403 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 9404 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 9405 } 9406 9407 // Set native library paths again. For moves, the path will be updated based on the 9408 // ABIs we've determined above. For non-moves, the path will be updated based on the 9409 // ABIs we determined during compilation, but the path will depend on the final 9410 // package path (after the rename away from the stage path). 9411 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9412 } 9413 9414 // This is a special case for the "system" package, where the ABI is 9415 // dictated by the zygote configuration (and init.rc). We should keep track 9416 // of this ABI so that we can deal with "normal" applications that run under 9417 // the same UID correctly. 9418 if (mPlatformPackage == pkg) { 9419 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 9420 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 9421 } 9422 9423 // If there's a mismatch between the abi-override in the package setting 9424 // and the abiOverride specified for the install. Warn about this because we 9425 // would've already compiled the app without taking the package setting into 9426 // account. 9427 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 9428 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 9429 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 9430 " for package " + pkg.packageName); 9431 } 9432 } 9433 9434 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9435 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9436 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 9437 9438 // Copy the derived override back to the parsed package, so that we can 9439 // update the package settings accordingly. 9440 pkg.cpuAbiOverride = cpuAbiOverride; 9441 9442 if (DEBUG_ABI_SELECTION) { 9443 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 9444 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 9445 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 9446 } 9447 9448 // Push the derived path down into PackageSettings so we know what to 9449 // clean up at uninstall time. 9450 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 9451 9452 if (DEBUG_ABI_SELECTION) { 9453 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 9454 " primary=" + pkg.applicationInfo.primaryCpuAbi + 9455 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 9456 } 9457 9458 // SIDE EFFECTS; removes DEX files from disk; move elsewhere 9459 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 9460 // We don't do this here during boot because we can do it all 9461 // at once after scanning all existing packages. 9462 // 9463 // We also do this *before* we perform dexopt on this package, so that 9464 // we can avoid redundant dexopts, and also to make sure we've got the 9465 // code and package path correct. 9466 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg); 9467 } 9468 9469 if (mFactoryTest && pkg.requestedPermissions.contains( 9470 android.Manifest.permission.FACTORY_TEST)) { 9471 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 9472 } 9473 9474 if (isSystemApp(pkg)) { 9475 pkgSetting.isOrphaned = true; 9476 } 9477 9478 // Take care of first install / last update times. 9479 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 9480 if (currentTime != 0) { 9481 if (pkgSetting.firstInstallTime == 0) { 9482 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 9483 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) { 9484 pkgSetting.lastUpdateTime = currentTime; 9485 } 9486 } else if (pkgSetting.firstInstallTime == 0) { 9487 // We need *something*. Take time time stamp of the file. 9488 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 9489 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 9490 if (scanFileTime != pkgSetting.timeStamp) { 9491 // A package on the system image has changed; consider this 9492 // to be an update. 9493 pkgSetting.lastUpdateTime = scanFileTime; 9494 } 9495 } 9496 pkgSetting.setTimeStamp(scanFileTime); 9497 9498 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 9499 if (nonMutatedPs != null) { 9500 synchronized (mPackages) { 9501 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 9502 } 9503 } 9504 } else { 9505 final int userId = user == null ? 0 : user.getIdentifier(); 9506 // Modify state for the given package setting 9507 commitPackageSettings(pkg, pkgSetting, user, scanFlags, 9508 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/); 9509 if (pkgSetting.getInstantApp(userId)) { 9510 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId); 9511 } 9512 } 9513 return pkg; 9514 } 9515 9516 /** 9517 * Applies policy to the parsed package based upon the given policy flags. 9518 * Ensures the package is in a good state. 9519 * <p> 9520 * Implementation detail: This method must NOT have any side effect. It would 9521 * ideally be static, but, it requires locks to read system state. 9522 */ 9523 private void applyPolicy(PackageParser.Package pkg, int policyFlags) { 9524 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 9525 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 9526 if (pkg.applicationInfo.isDirectBootAware()) { 9527 // we're direct boot aware; set for all components 9528 for (PackageParser.Service s : pkg.services) { 9529 s.info.encryptionAware = s.info.directBootAware = true; 9530 } 9531 for (PackageParser.Provider p : pkg.providers) { 9532 p.info.encryptionAware = p.info.directBootAware = true; 9533 } 9534 for (PackageParser.Activity a : pkg.activities) { 9535 a.info.encryptionAware = a.info.directBootAware = true; 9536 } 9537 for (PackageParser.Activity r : pkg.receivers) { 9538 r.info.encryptionAware = r.info.directBootAware = true; 9539 } 9540 } 9541 } else { 9542 // Only allow system apps to be flagged as core apps. 9543 pkg.coreApp = false; 9544 // clear flags not applicable to regular apps 9545 pkg.applicationInfo.privateFlags &= 9546 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 9547 pkg.applicationInfo.privateFlags &= 9548 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 9549 } 9550 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 9551 9552 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 9553 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 9554 } 9555 9556 if (!isSystemApp(pkg)) { 9557 // Only system apps can use these features. 9558 pkg.mOriginalPackages = null; 9559 pkg.mRealPackage = null; 9560 pkg.mAdoptPermissions = null; 9561 } 9562 } 9563 9564 /** 9565 * Asserts the parsed package is valid according to the given policy. If the 9566 * package is invalid, for whatever reason, throws {@link PackageManagerException}. 9567 * <p> 9568 * Implementation detail: This method must NOT have any side effects. It would 9569 * ideally be static, but, it requires locks to read system state. 9570 * 9571 * @throws PackageManagerException If the package fails any of the validation checks 9572 */ 9573 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags) 9574 throws PackageManagerException { 9575 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 9576 assertCodePolicy(pkg); 9577 } 9578 9579 if (pkg.applicationInfo.getCodePath() == null || 9580 pkg.applicationInfo.getResourcePath() == null) { 9581 // Bail out. The resource and code paths haven't been set. 9582 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 9583 "Code and resource paths haven't been set correctly"); 9584 } 9585 9586 // Make sure we're not adding any bogus keyset info 9587 KeySetManagerService ksms = mSettings.mKeySetManagerService; 9588 ksms.assertScannedPackageValid(pkg); 9589 9590 synchronized (mPackages) { 9591 // The special "android" package can only be defined once 9592 if (pkg.packageName.equals("android")) { 9593 if (mAndroidApplication != null) { 9594 Slog.w(TAG, "*************************************************"); 9595 Slog.w(TAG, "Core android package being redefined. Skipping."); 9596 Slog.w(TAG, " codePath=" + pkg.codePath); 9597 Slog.w(TAG, "*************************************************"); 9598 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 9599 "Core android package being redefined. Skipping."); 9600 } 9601 } 9602 9603 // A package name must be unique; don't allow duplicates 9604 if (mPackages.containsKey(pkg.packageName)) { 9605 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 9606 "Application package " + pkg.packageName 9607 + " already installed. Skipping duplicate."); 9608 } 9609 9610 if (pkg.applicationInfo.isStaticSharedLibrary()) { 9611 // Static libs have a synthetic package name containing the version 9612 // but we still want the base name to be unique. 9613 if (mPackages.containsKey(pkg.manifestPackageName)) { 9614 throw new PackageManagerException( 9615 "Duplicate static shared lib provider package"); 9616 } 9617 9618 // Static shared libraries should have at least O target SDK 9619 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) { 9620 throw new PackageManagerException( 9621 "Packages declaring static-shared libs must target O SDK or higher"); 9622 } 9623 9624 // Package declaring static a shared lib cannot be instant apps 9625 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 9626 throw new PackageManagerException( 9627 "Packages declaring static-shared libs cannot be instant apps"); 9628 } 9629 9630 // Package declaring static a shared lib cannot be renamed since the package 9631 // name is synthetic and apps can't code around package manager internals. 9632 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) { 9633 throw new PackageManagerException( 9634 "Packages declaring static-shared libs cannot be renamed"); 9635 } 9636 9637 // Package declaring static a shared lib cannot declare child packages 9638 if (!ArrayUtils.isEmpty(pkg.childPackages)) { 9639 throw new PackageManagerException( 9640 "Packages declaring static-shared libs cannot have child packages"); 9641 } 9642 9643 // Package declaring static a shared lib cannot declare dynamic libs 9644 if (!ArrayUtils.isEmpty(pkg.libraryNames)) { 9645 throw new PackageManagerException( 9646 "Packages declaring static-shared libs cannot declare dynamic libs"); 9647 } 9648 9649 // Package declaring static a shared lib cannot declare shared users 9650 if (pkg.mSharedUserId != null) { 9651 throw new PackageManagerException( 9652 "Packages declaring static-shared libs cannot declare shared users"); 9653 } 9654 9655 // Static shared libs cannot declare activities 9656 if (!pkg.activities.isEmpty()) { 9657 throw new PackageManagerException( 9658 "Static shared libs cannot declare activities"); 9659 } 9660 9661 // Static shared libs cannot declare services 9662 if (!pkg.services.isEmpty()) { 9663 throw new PackageManagerException( 9664 "Static shared libs cannot declare services"); 9665 } 9666 9667 // Static shared libs cannot declare providers 9668 if (!pkg.providers.isEmpty()) { 9669 throw new PackageManagerException( 9670 "Static shared libs cannot declare content providers"); 9671 } 9672 9673 // Static shared libs cannot declare receivers 9674 if (!pkg.receivers.isEmpty()) { 9675 throw new PackageManagerException( 9676 "Static shared libs cannot declare broadcast receivers"); 9677 } 9678 9679 // Static shared libs cannot declare permission groups 9680 if (!pkg.permissionGroups.isEmpty()) { 9681 throw new PackageManagerException( 9682 "Static shared libs cannot declare permission groups"); 9683 } 9684 9685 // Static shared libs cannot declare permissions 9686 if (!pkg.permissions.isEmpty()) { 9687 throw new PackageManagerException( 9688 "Static shared libs cannot declare permissions"); 9689 } 9690 9691 // Static shared libs cannot declare protected broadcasts 9692 if (pkg.protectedBroadcasts != null) { 9693 throw new PackageManagerException( 9694 "Static shared libs cannot declare protected broadcasts"); 9695 } 9696 9697 // Static shared libs cannot be overlay targets 9698 if (pkg.mOverlayTarget != null) { 9699 throw new PackageManagerException( 9700 "Static shared libs cannot be overlay targets"); 9701 } 9702 9703 // The version codes must be ordered as lib versions 9704 int minVersionCode = Integer.MIN_VALUE; 9705 int maxVersionCode = Integer.MAX_VALUE; 9706 9707 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get( 9708 pkg.staticSharedLibName); 9709 if (versionedLib != null) { 9710 final int versionCount = versionedLib.size(); 9711 for (int i = 0; i < versionCount; i++) { 9712 SharedLibraryInfo libInfo = versionedLib.valueAt(i).info; 9713 // TODO: We will change version code to long, so in the new API it is long 9714 final int libVersionCode = (int) libInfo.getDeclaringPackage() 9715 .getVersionCode(); 9716 if (libInfo.getVersion() < pkg.staticSharedLibVersion) { 9717 minVersionCode = Math.max(minVersionCode, libVersionCode + 1); 9718 } else if (libInfo.getVersion() > pkg.staticSharedLibVersion) { 9719 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1); 9720 } else { 9721 minVersionCode = maxVersionCode = libVersionCode; 9722 break; 9723 } 9724 } 9725 } 9726 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) { 9727 throw new PackageManagerException("Static shared" 9728 + " lib version codes must be ordered as lib versions"); 9729 } 9730 } 9731 9732 // Only privileged apps and updated privileged apps can add child packages. 9733 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 9734 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 9735 throw new PackageManagerException("Only privileged apps can add child " 9736 + "packages. Ignoring package " + pkg.packageName); 9737 } 9738 final int childCount = pkg.childPackages.size(); 9739 for (int i = 0; i < childCount; i++) { 9740 PackageParser.Package childPkg = pkg.childPackages.get(i); 9741 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 9742 childPkg.packageName)) { 9743 throw new PackageManagerException("Can't override child of " 9744 + "another disabled app. Ignoring package " + pkg.packageName); 9745 } 9746 } 9747 } 9748 9749 // If we're only installing presumed-existing packages, require that the 9750 // scanned APK is both already known and at the path previously established 9751 // for it. Previously unknown packages we pick up normally, but if we have an 9752 // a priori expectation about this package's install presence, enforce it. 9753 // With a singular exception for new system packages. When an OTA contains 9754 // a new system package, we allow the codepath to change from a system location 9755 // to the user-installed location. If we don't allow this change, any newer, 9756 // user-installed version of the application will be ignored. 9757 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 9758 if (mExpectingBetter.containsKey(pkg.packageName)) { 9759 logCriticalInfo(Log.WARN, 9760 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 9761 } else { 9762 PackageSetting known = mSettings.getPackageLPr(pkg.packageName); 9763 if (known != null) { 9764 if (DEBUG_PACKAGE_SCANNING) { 9765 Log.d(TAG, "Examining " + pkg.codePath 9766 + " and requiring known paths " + known.codePathString 9767 + " & " + known.resourcePathString); 9768 } 9769 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 9770 || !pkg.applicationInfo.getResourcePath().equals( 9771 known.resourcePathString)) { 9772 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 9773 "Application package " + pkg.packageName 9774 + " found at " + pkg.applicationInfo.getCodePath() 9775 + " but expected at " + known.codePathString 9776 + "; ignoring."); 9777 } 9778 } 9779 } 9780 } 9781 9782 // Verify that this new package doesn't have any content providers 9783 // that conflict with existing packages. Only do this if the 9784 // package isn't already installed, since we don't want to break 9785 // things that are installed. 9786 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 9787 final int N = pkg.providers.size(); 9788 int i; 9789 for (i=0; i<N; i++) { 9790 PackageParser.Provider p = pkg.providers.get(i); 9791 if (p.info.authority != null) { 9792 String names[] = p.info.authority.split(";"); 9793 for (int j = 0; j < names.length; j++) { 9794 if (mProvidersByAuthority.containsKey(names[j])) { 9795 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 9796 final String otherPackageName = 9797 ((other != null && other.getComponentName() != null) ? 9798 other.getComponentName().getPackageName() : "?"); 9799 throw new PackageManagerException( 9800 INSTALL_FAILED_CONFLICTING_PROVIDER, 9801 "Can't install because provider name " + names[j] 9802 + " (in package " + pkg.applicationInfo.packageName 9803 + ") is already used by " + otherPackageName); 9804 } 9805 } 9806 } 9807 } 9808 } 9809 } 9810 } 9811 9812 private boolean addSharedLibraryLPw(String path, String apk, String name, int version, 9813 int type, String declaringPackageName, int declaringVersionCode) { 9814 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 9815 if (versionedLib == null) { 9816 versionedLib = new SparseArray<>(); 9817 mSharedLibraries.put(name, versionedLib); 9818 if (type == SharedLibraryInfo.TYPE_STATIC) { 9819 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib); 9820 } 9821 } else if (versionedLib.indexOfKey(version) >= 0) { 9822 return false; 9823 } 9824 SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name, 9825 version, type, declaringPackageName, declaringVersionCode); 9826 versionedLib.put(version, libEntry); 9827 return true; 9828 } 9829 9830 private boolean removeSharedLibraryLPw(String name, int version) { 9831 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 9832 if (versionedLib == null) { 9833 return false; 9834 } 9835 final int libIdx = versionedLib.indexOfKey(version); 9836 if (libIdx < 0) { 9837 return false; 9838 } 9839 SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx); 9840 versionedLib.remove(version); 9841 if (versionedLib.size() <= 0) { 9842 mSharedLibraries.remove(name); 9843 if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) { 9844 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage() 9845 .getPackageName()); 9846 } 9847 } 9848 return true; 9849 } 9850 9851 /** 9852 * Adds a scanned package to the system. When this method is finished, the package will 9853 * be available for query, resolution, etc... 9854 */ 9855 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting, 9856 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException { 9857 final String pkgName = pkg.packageName; 9858 if (mCustomResolverComponentName != null && 9859 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 9860 setUpCustomResolverActivity(pkg); 9861 } 9862 9863 if (pkg.packageName.equals("android")) { 9864 synchronized (mPackages) { 9865 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 9866 // Set up information for our fall-back user intent resolution activity. 9867 mPlatformPackage = pkg; 9868 pkg.mVersionCode = mSdkVersion; 9869 mAndroidApplication = pkg.applicationInfo; 9870 if (!mResolverReplaced) { 9871 mResolveActivity.applicationInfo = mAndroidApplication; 9872 mResolveActivity.name = ResolverActivity.class.getName(); 9873 mResolveActivity.packageName = mAndroidApplication.packageName; 9874 mResolveActivity.processName = "system:ui"; 9875 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9876 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 9877 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 9878 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 9879 mResolveActivity.exported = true; 9880 mResolveActivity.enabled = true; 9881 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 9882 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 9883 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 9884 | ActivityInfo.CONFIG_SCREEN_LAYOUT 9885 | ActivityInfo.CONFIG_ORIENTATION 9886 | ActivityInfo.CONFIG_KEYBOARD 9887 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 9888 mResolveInfo.activityInfo = mResolveActivity; 9889 mResolveInfo.priority = 0; 9890 mResolveInfo.preferredOrder = 0; 9891 mResolveInfo.match = 0; 9892 mResolveComponentName = new ComponentName( 9893 mAndroidApplication.packageName, mResolveActivity.name); 9894 } 9895 } 9896 } 9897 } 9898 9899 ArrayList<PackageParser.Package> clientLibPkgs = null; 9900 // writer 9901 synchronized (mPackages) { 9902 boolean hasStaticSharedLibs = false; 9903 9904 // Any app can add new static shared libraries 9905 if (pkg.staticSharedLibName != null) { 9906 // Static shared libs don't allow renaming as they have synthetic package 9907 // names to allow install of multiple versions, so use name from manifest. 9908 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName, 9909 pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC, 9910 pkg.manifestPackageName, pkg.mVersionCode)) { 9911 hasStaticSharedLibs = true; 9912 } else { 9913 Slog.w(TAG, "Package " + pkg.packageName + " library " 9914 + pkg.staticSharedLibName + " already exists; skipping"); 9915 } 9916 // Static shared libs cannot be updated once installed since they 9917 // use synthetic package name which includes the version code, so 9918 // not need to update other packages's shared lib dependencies. 9919 } 9920 9921 if (!hasStaticSharedLibs 9922 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9923 // Only system apps can add new dynamic shared libraries. 9924 if (pkg.libraryNames != null) { 9925 for (int i = 0; i < pkg.libraryNames.size(); i++) { 9926 String name = pkg.libraryNames.get(i); 9927 boolean allowed = false; 9928 if (pkg.isUpdatedSystemApp()) { 9929 // New library entries can only be added through the 9930 // system image. This is important to get rid of a lot 9931 // of nasty edge cases: for example if we allowed a non- 9932 // system update of the app to add a library, then uninstalling 9933 // the update would make the library go away, and assumptions 9934 // we made such as through app install filtering would now 9935 // have allowed apps on the device which aren't compatible 9936 // with it. Better to just have the restriction here, be 9937 // conservative, and create many fewer cases that can negatively 9938 // impact the user experience. 9939 final PackageSetting sysPs = mSettings 9940 .getDisabledSystemPkgLPr(pkg.packageName); 9941 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 9942 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) { 9943 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 9944 allowed = true; 9945 break; 9946 } 9947 } 9948 } 9949 } else { 9950 allowed = true; 9951 } 9952 if (allowed) { 9953 if (!addSharedLibraryLPw(null, pkg.packageName, name, 9954 SharedLibraryInfo.VERSION_UNDEFINED, 9955 SharedLibraryInfo.TYPE_DYNAMIC, 9956 pkg.packageName, pkg.mVersionCode)) { 9957 Slog.w(TAG, "Package " + pkg.packageName + " library " 9958 + name + " already exists; skipping"); 9959 } 9960 } else { 9961 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 9962 + name + " that is not declared on system image; skipping"); 9963 } 9964 } 9965 9966 if ((scanFlags & SCAN_BOOTING) == 0) { 9967 // If we are not booting, we need to update any applications 9968 // that are clients of our shared library. If we are booting, 9969 // this will all be done once the scan is complete. 9970 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 9971 } 9972 } 9973 } 9974 } 9975 9976 if ((scanFlags & SCAN_BOOTING) != 0) { 9977 // No apps can run during boot scan, so they don't need to be frozen 9978 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 9979 // Caller asked to not kill app, so it's probably not frozen 9980 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 9981 // Caller asked us to ignore frozen check for some reason; they 9982 // probably didn't know the package name 9983 } else { 9984 // We're doing major surgery on this package, so it better be frozen 9985 // right now to keep it from launching 9986 checkPackageFrozen(pkgName); 9987 } 9988 9989 // Also need to kill any apps that are dependent on the library. 9990 if (clientLibPkgs != null) { 9991 for (int i=0; i<clientLibPkgs.size(); i++) { 9992 PackageParser.Package clientPkg = clientLibPkgs.get(i); 9993 killApplication(clientPkg.applicationInfo.packageName, 9994 clientPkg.applicationInfo.uid, "update lib"); 9995 } 9996 } 9997 9998 // writer 9999 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 10000 10001 synchronized (mPackages) { 10002 // We don't expect installation to fail beyond this point 10003 10004 // Add the new setting to mSettings 10005 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 10006 // Add the new setting to mPackages 10007 mPackages.put(pkg.applicationInfo.packageName, pkg); 10008 // Make sure we don't accidentally delete its data. 10009 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 10010 while (iter.hasNext()) { 10011 PackageCleanItem item = iter.next(); 10012 if (pkgName.equals(item.packageName)) { 10013 iter.remove(); 10014 } 10015 } 10016 10017 // Add the package's KeySets to the global KeySetManagerService 10018 KeySetManagerService ksms = mSettings.mKeySetManagerService; 10019 ksms.addScannedPackageLPw(pkg); 10020 10021 int N = pkg.providers.size(); 10022 StringBuilder r = null; 10023 int i; 10024 for (i=0; i<N; i++) { 10025 PackageParser.Provider p = pkg.providers.get(i); 10026 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 10027 p.info.processName); 10028 mProviders.addProvider(p); 10029 p.syncable = p.info.isSyncable; 10030 if (p.info.authority != null) { 10031 String names[] = p.info.authority.split(";"); 10032 p.info.authority = null; 10033 for (int j = 0; j < names.length; j++) { 10034 if (j == 1 && p.syncable) { 10035 // We only want the first authority for a provider to possibly be 10036 // syncable, so if we already added this provider using a different 10037 // authority clear the syncable flag. We copy the provider before 10038 // changing it because the mProviders object contains a reference 10039 // to a provider that we don't want to change. 10040 // Only do this for the second authority since the resulting provider 10041 // object can be the same for all future authorities for this provider. 10042 p = new PackageParser.Provider(p); 10043 p.syncable = false; 10044 } 10045 if (!mProvidersByAuthority.containsKey(names[j])) { 10046 mProvidersByAuthority.put(names[j], p); 10047 if (p.info.authority == null) { 10048 p.info.authority = names[j]; 10049 } else { 10050 p.info.authority = p.info.authority + ";" + names[j]; 10051 } 10052 if (DEBUG_PACKAGE_SCANNING) { 10053 if (chatty) 10054 Log.d(TAG, "Registered content provider: " + names[j] 10055 + ", className = " + p.info.name + ", isSyncable = " 10056 + p.info.isSyncable); 10057 } 10058 } else { 10059 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 10060 Slog.w(TAG, "Skipping provider name " + names[j] + 10061 " (in package " + pkg.applicationInfo.packageName + 10062 "): name already used by " 10063 + ((other != null && other.getComponentName() != null) 10064 ? other.getComponentName().getPackageName() : "?")); 10065 } 10066 } 10067 } 10068 if (chatty) { 10069 if (r == null) { 10070 r = new StringBuilder(256); 10071 } else { 10072 r.append(' '); 10073 } 10074 r.append(p.info.name); 10075 } 10076 } 10077 if (r != null) { 10078 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 10079 } 10080 10081 N = pkg.services.size(); 10082 r = null; 10083 for (i=0; i<N; i++) { 10084 PackageParser.Service s = pkg.services.get(i); 10085 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 10086 s.info.processName); 10087 mServices.addService(s); 10088 if (chatty) { 10089 if (r == null) { 10090 r = new StringBuilder(256); 10091 } else { 10092 r.append(' '); 10093 } 10094 r.append(s.info.name); 10095 } 10096 } 10097 if (r != null) { 10098 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 10099 } 10100 10101 N = pkg.receivers.size(); 10102 r = null; 10103 for (i=0; i<N; i++) { 10104 PackageParser.Activity a = pkg.receivers.get(i); 10105 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 10106 a.info.processName); 10107 mReceivers.addActivity(a, "receiver"); 10108 if (chatty) { 10109 if (r == null) { 10110 r = new StringBuilder(256); 10111 } else { 10112 r.append(' '); 10113 } 10114 r.append(a.info.name); 10115 } 10116 } 10117 if (r != null) { 10118 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 10119 } 10120 10121 N = pkg.activities.size(); 10122 r = null; 10123 for (i=0; i<N; i++) { 10124 PackageParser.Activity a = pkg.activities.get(i); 10125 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 10126 a.info.processName); 10127 mActivities.addActivity(a, "activity"); 10128 if (chatty) { 10129 if (r == null) { 10130 r = new StringBuilder(256); 10131 } else { 10132 r.append(' '); 10133 } 10134 r.append(a.info.name); 10135 } 10136 } 10137 if (r != null) { 10138 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 10139 } 10140 10141 N = pkg.permissionGroups.size(); 10142 r = null; 10143 for (i=0; i<N; i++) { 10144 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 10145 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 10146 final String curPackageName = cur == null ? null : cur.info.packageName; 10147 // Dont allow ephemeral apps to define new permission groups. 10148 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 10149 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 10150 + pg.info.packageName 10151 + " ignored: instant apps cannot define new permission groups."); 10152 continue; 10153 } 10154 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 10155 if (cur == null || isPackageUpdate) { 10156 mPermissionGroups.put(pg.info.name, pg); 10157 if (chatty) { 10158 if (r == null) { 10159 r = new StringBuilder(256); 10160 } else { 10161 r.append(' '); 10162 } 10163 if (isPackageUpdate) { 10164 r.append("UPD:"); 10165 } 10166 r.append(pg.info.name); 10167 } 10168 } else { 10169 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 10170 + pg.info.packageName + " ignored: original from " 10171 + cur.info.packageName); 10172 if (chatty) { 10173 if (r == null) { 10174 r = new StringBuilder(256); 10175 } else { 10176 r.append(' '); 10177 } 10178 r.append("DUP:"); 10179 r.append(pg.info.name); 10180 } 10181 } 10182 } 10183 if (r != null) { 10184 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 10185 } 10186 10187 N = pkg.permissions.size(); 10188 r = null; 10189 for (i=0; i<N; i++) { 10190 PackageParser.Permission p = pkg.permissions.get(i); 10191 10192 // Dont allow ephemeral apps to define new permissions. 10193 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 10194 Slog.w(TAG, "Permission " + p.info.name + " from package " 10195 + p.info.packageName 10196 + " ignored: instant apps cannot define new permissions."); 10197 continue; 10198 } 10199 10200 // Assume by default that we did not install this permission into the system. 10201 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 10202 10203 // Now that permission groups have a special meaning, we ignore permission 10204 // groups for legacy apps to prevent unexpected behavior. In particular, 10205 // permissions for one app being granted to someone just becase they happen 10206 // to be in a group defined by another app (before this had no implications). 10207 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 10208 p.group = mPermissionGroups.get(p.info.group); 10209 // Warn for a permission in an unknown group. 10210 if (p.info.group != null && p.group == null) { 10211 Slog.w(TAG, "Permission " + p.info.name + " from package " 10212 + p.info.packageName + " in an unknown group " + p.info.group); 10213 } 10214 } 10215 10216 ArrayMap<String, BasePermission> permissionMap = 10217 p.tree ? mSettings.mPermissionTrees 10218 : mSettings.mPermissions; 10219 BasePermission bp = permissionMap.get(p.info.name); 10220 10221 // Allow system apps to redefine non-system permissions 10222 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 10223 final boolean currentOwnerIsSystem = (bp.perm != null 10224 && isSystemApp(bp.perm.owner)); 10225 if (isSystemApp(p.owner)) { 10226 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 10227 // It's a built-in permission and no owner, take ownership now 10228 bp.packageSetting = pkgSetting; 10229 bp.perm = p; 10230 bp.uid = pkg.applicationInfo.uid; 10231 bp.sourcePackage = p.info.packageName; 10232 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 10233 } else if (!currentOwnerIsSystem) { 10234 String msg = "New decl " + p.owner + " of permission " 10235 + p.info.name + " is system; overriding " + bp.sourcePackage; 10236 reportSettingsProblem(Log.WARN, msg); 10237 bp = null; 10238 } 10239 } 10240 } 10241 10242 if (bp == null) { 10243 bp = new BasePermission(p.info.name, p.info.packageName, 10244 BasePermission.TYPE_NORMAL); 10245 permissionMap.put(p.info.name, bp); 10246 } 10247 10248 if (bp.perm == null) { 10249 if (bp.sourcePackage == null 10250 || bp.sourcePackage.equals(p.info.packageName)) { 10251 BasePermission tree = findPermissionTreeLP(p.info.name); 10252 if (tree == null 10253 || tree.sourcePackage.equals(p.info.packageName)) { 10254 bp.packageSetting = pkgSetting; 10255 bp.perm = p; 10256 bp.uid = pkg.applicationInfo.uid; 10257 bp.sourcePackage = p.info.packageName; 10258 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 10259 if (chatty) { 10260 if (r == null) { 10261 r = new StringBuilder(256); 10262 } else { 10263 r.append(' '); 10264 } 10265 r.append(p.info.name); 10266 } 10267 } else { 10268 Slog.w(TAG, "Permission " + p.info.name + " from package " 10269 + p.info.packageName + " ignored: base tree " 10270 + tree.name + " is from package " 10271 + tree.sourcePackage); 10272 } 10273 } else { 10274 Slog.w(TAG, "Permission " + p.info.name + " from package " 10275 + p.info.packageName + " ignored: original from " 10276 + bp.sourcePackage); 10277 } 10278 } else if (chatty) { 10279 if (r == null) { 10280 r = new StringBuilder(256); 10281 } else { 10282 r.append(' '); 10283 } 10284 r.append("DUP:"); 10285 r.append(p.info.name); 10286 } 10287 if (bp.perm == p) { 10288 bp.protectionLevel = p.info.protectionLevel; 10289 } 10290 } 10291 10292 if (r != null) { 10293 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 10294 } 10295 10296 N = pkg.instrumentation.size(); 10297 r = null; 10298 for (i=0; i<N; i++) { 10299 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 10300 a.info.packageName = pkg.applicationInfo.packageName; 10301 a.info.sourceDir = pkg.applicationInfo.sourceDir; 10302 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 10303 a.info.splitNames = pkg.splitNames; 10304 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 10305 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 10306 a.info.splitDependencies = pkg.applicationInfo.splitDependencies; 10307 a.info.dataDir = pkg.applicationInfo.dataDir; 10308 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 10309 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 10310 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 10311 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 10312 mInstrumentation.put(a.getComponentName(), a); 10313 if (chatty) { 10314 if (r == null) { 10315 r = new StringBuilder(256); 10316 } else { 10317 r.append(' '); 10318 } 10319 r.append(a.info.name); 10320 } 10321 } 10322 if (r != null) { 10323 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 10324 } 10325 10326 if (pkg.protectedBroadcasts != null) { 10327 N = pkg.protectedBroadcasts.size(); 10328 for (i=0; i<N; i++) { 10329 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 10330 } 10331 } 10332 } 10333 10334 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10335 } 10336 10337 /** 10338 * Derive the ABI of a non-system package located at {@code scanFile}. This information 10339 * is derived purely on the basis of the contents of {@code scanFile} and 10340 * {@code cpuAbiOverride}. 10341 * 10342 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 10343 */ 10344 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile, 10345 String cpuAbiOverride, boolean extractLibs, 10346 File appLib32InstallDir) 10347 throws PackageManagerException { 10348 // Give ourselves some initial paths; we'll come back for another 10349 // pass once we've determined ABI below. 10350 setNativeLibraryPaths(pkg, appLib32InstallDir); 10351 10352 // We would never need to extract libs for forward-locked and external packages, 10353 // since the container service will do it for us. We shouldn't attempt to 10354 // extract libs from system app when it was not updated. 10355 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 10356 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 10357 extractLibs = false; 10358 } 10359 10360 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 10361 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 10362 10363 NativeLibraryHelper.Handle handle = null; 10364 try { 10365 handle = NativeLibraryHelper.Handle.create(pkg); 10366 // TODO(multiArch): This can be null for apps that didn't go through the 10367 // usual installation process. We can calculate it again, like we 10368 // do during install time. 10369 // 10370 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 10371 // unnecessary. 10372 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 10373 10374 // Null out the abis so that they can be recalculated. 10375 pkg.applicationInfo.primaryCpuAbi = null; 10376 pkg.applicationInfo.secondaryCpuAbi = null; 10377 if (isMultiArch(pkg.applicationInfo)) { 10378 // Warn if we've set an abiOverride for multi-lib packages.. 10379 // By definition, we need to copy both 32 and 64 bit libraries for 10380 // such packages. 10381 if (pkg.cpuAbiOverride != null 10382 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 10383 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 10384 } 10385 10386 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 10387 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 10388 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 10389 if (extractLibs) { 10390 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10391 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10392 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 10393 useIsaSpecificSubdirs); 10394 } else { 10395 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10396 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 10397 } 10398 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10399 } 10400 10401 maybeThrowExceptionForMultiArchCopy( 10402 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 10403 10404 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 10405 if (extractLibs) { 10406 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10407 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10408 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 10409 useIsaSpecificSubdirs); 10410 } else { 10411 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10412 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 10413 } 10414 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10415 } 10416 10417 maybeThrowExceptionForMultiArchCopy( 10418 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 10419 10420 if (abi64 >= 0) { 10421 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 10422 } 10423 10424 if (abi32 >= 0) { 10425 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 10426 if (abi64 >= 0) { 10427 if (pkg.use32bitAbi) { 10428 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 10429 pkg.applicationInfo.primaryCpuAbi = abi; 10430 } else { 10431 pkg.applicationInfo.secondaryCpuAbi = abi; 10432 } 10433 } else { 10434 pkg.applicationInfo.primaryCpuAbi = abi; 10435 } 10436 } 10437 10438 } else { 10439 String[] abiList = (cpuAbiOverride != null) ? 10440 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 10441 10442 // Enable gross and lame hacks for apps that are built with old 10443 // SDK tools. We must scan their APKs for renderscript bitcode and 10444 // not launch them if it's present. Don't bother checking on devices 10445 // that don't have 64 bit support. 10446 boolean needsRenderScriptOverride = false; 10447 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 10448 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 10449 abiList = Build.SUPPORTED_32_BIT_ABIS; 10450 needsRenderScriptOverride = true; 10451 } 10452 10453 final int copyRet; 10454 if (extractLibs) { 10455 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10456 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10457 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 10458 } else { 10459 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10460 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 10461 } 10462 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10463 10464 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 10465 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 10466 "Error unpackaging native libs for app, errorCode=" + copyRet); 10467 } 10468 10469 if (copyRet >= 0) { 10470 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 10471 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 10472 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 10473 } else if (needsRenderScriptOverride) { 10474 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 10475 } 10476 } 10477 } catch (IOException ioe) { 10478 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 10479 } finally { 10480 IoUtils.closeQuietly(handle); 10481 } 10482 10483 // Now that we've calculated the ABIs and determined if it's an internal app, 10484 // we will go ahead and populate the nativeLibraryPath. 10485 setNativeLibraryPaths(pkg, appLib32InstallDir); 10486 } 10487 10488 /** 10489 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 10490 * i.e, so that all packages can be run inside a single process if required. 10491 * 10492 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 10493 * this function will either try and make the ABI for all packages in {@code packagesForUser} 10494 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 10495 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 10496 * updating a package that belongs to a shared user. 10497 * 10498 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 10499 * adds unnecessary complexity. 10500 */ 10501 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 10502 PackageParser.Package scannedPackage) { 10503 String requiredInstructionSet = null; 10504 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 10505 requiredInstructionSet = VMRuntime.getInstructionSet( 10506 scannedPackage.applicationInfo.primaryCpuAbi); 10507 } 10508 10509 PackageSetting requirer = null; 10510 for (PackageSetting ps : packagesForUser) { 10511 // If packagesForUser contains scannedPackage, we skip it. This will happen 10512 // when scannedPackage is an update of an existing package. Without this check, 10513 // we will never be able to change the ABI of any package belonging to a shared 10514 // user, even if it's compatible with other packages. 10515 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 10516 if (ps.primaryCpuAbiString == null) { 10517 continue; 10518 } 10519 10520 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 10521 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 10522 // We have a mismatch between instruction sets (say arm vs arm64) warn about 10523 // this but there's not much we can do. 10524 String errorMessage = "Instruction set mismatch, " 10525 + ((requirer == null) ? "[caller]" : requirer) 10526 + " requires " + requiredInstructionSet + " whereas " + ps 10527 + " requires " + instructionSet; 10528 Slog.w(TAG, errorMessage); 10529 } 10530 10531 if (requiredInstructionSet == null) { 10532 requiredInstructionSet = instructionSet; 10533 requirer = ps; 10534 } 10535 } 10536 } 10537 10538 if (requiredInstructionSet != null) { 10539 String adjustedAbi; 10540 if (requirer != null) { 10541 // requirer != null implies that either scannedPackage was null or that scannedPackage 10542 // did not require an ABI, in which case we have to adjust scannedPackage to match 10543 // the ABI of the set (which is the same as requirer's ABI) 10544 adjustedAbi = requirer.primaryCpuAbiString; 10545 if (scannedPackage != null) { 10546 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 10547 } 10548 } else { 10549 // requirer == null implies that we're updating all ABIs in the set to 10550 // match scannedPackage. 10551 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 10552 } 10553 10554 for (PackageSetting ps : packagesForUser) { 10555 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 10556 if (ps.primaryCpuAbiString != null) { 10557 continue; 10558 } 10559 10560 ps.primaryCpuAbiString = adjustedAbi; 10561 if (ps.pkg != null && ps.pkg.applicationInfo != null && 10562 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 10563 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 10564 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 10565 + " (requirer=" 10566 + (requirer == null ? "null" : requirer.pkg.packageName) 10567 + ", scannedPackage=" 10568 + (scannedPackage != null ? scannedPackage.packageName : "null") 10569 + ")"); 10570 try { 10571 mInstaller.rmdex(ps.codePathString, 10572 getDexCodeInstructionSet(getPreferredInstructionSet())); 10573 } catch (InstallerException ignored) { 10574 } 10575 } 10576 } 10577 } 10578 } 10579 } 10580 10581 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 10582 synchronized (mPackages) { 10583 mResolverReplaced = true; 10584 // Set up information for custom user intent resolution activity. 10585 mResolveActivity.applicationInfo = pkg.applicationInfo; 10586 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 10587 mResolveActivity.packageName = pkg.applicationInfo.packageName; 10588 mResolveActivity.processName = pkg.applicationInfo.packageName; 10589 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 10590 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 10591 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 10592 mResolveActivity.theme = 0; 10593 mResolveActivity.exported = true; 10594 mResolveActivity.enabled = true; 10595 mResolveInfo.activityInfo = mResolveActivity; 10596 mResolveInfo.priority = 0; 10597 mResolveInfo.preferredOrder = 0; 10598 mResolveInfo.match = 0; 10599 mResolveComponentName = mCustomResolverComponentName; 10600 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 10601 mResolveComponentName); 10602 } 10603 } 10604 10605 private void setUpInstantAppInstallerActivityLP(ComponentName installerComponent) { 10606 if (installerComponent == null) { 10607 if (DEBUG_EPHEMERAL) { 10608 Slog.d(TAG, "Clear ephemeral installer activity"); 10609 } 10610 mInstantAppInstallerActivity.applicationInfo = null; 10611 return; 10612 } 10613 10614 if (DEBUG_EPHEMERAL) { 10615 Slog.d(TAG, "Set ephemeral installer activity: " + installerComponent); 10616 } 10617 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 10618 // Set up information for ephemeral installer activity 10619 mInstantAppInstallerActivity.applicationInfo = pkg.applicationInfo; 10620 mInstantAppInstallerActivity.name = installerComponent.getClassName(); 10621 mInstantAppInstallerActivity.packageName = pkg.applicationInfo.packageName; 10622 mInstantAppInstallerActivity.processName = pkg.applicationInfo.packageName; 10623 mInstantAppInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 10624 mInstantAppInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 10625 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 10626 mInstantAppInstallerActivity.theme = 0; 10627 mInstantAppInstallerActivity.exported = true; 10628 mInstantAppInstallerActivity.enabled = true; 10629 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity; 10630 mInstantAppInstallerInfo.priority = 0; 10631 mInstantAppInstallerInfo.preferredOrder = 1; 10632 mInstantAppInstallerInfo.isDefault = true; 10633 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 10634 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 10635 } 10636 10637 private static String calculateBundledApkRoot(final String codePathString) { 10638 final File codePath = new File(codePathString); 10639 final File codeRoot; 10640 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 10641 codeRoot = Environment.getRootDirectory(); 10642 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 10643 codeRoot = Environment.getOemDirectory(); 10644 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 10645 codeRoot = Environment.getVendorDirectory(); 10646 } else { 10647 // Unrecognized code path; take its top real segment as the apk root: 10648 // e.g. /something/app/blah.apk => /something 10649 try { 10650 File f = codePath.getCanonicalFile(); 10651 File parent = f.getParentFile(); // non-null because codePath is a file 10652 File tmp; 10653 while ((tmp = parent.getParentFile()) != null) { 10654 f = parent; 10655 parent = tmp; 10656 } 10657 codeRoot = f; 10658 Slog.w(TAG, "Unrecognized code path " 10659 + codePath + " - using " + codeRoot); 10660 } catch (IOException e) { 10661 // Can't canonicalize the code path -- shenanigans? 10662 Slog.w(TAG, "Can't canonicalize code path " + codePath); 10663 return Environment.getRootDirectory().getPath(); 10664 } 10665 } 10666 return codeRoot.getPath(); 10667 } 10668 10669 /** 10670 * Derive and set the location of native libraries for the given package, 10671 * which varies depending on where and how the package was installed. 10672 */ 10673 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) { 10674 final ApplicationInfo info = pkg.applicationInfo; 10675 final String codePath = pkg.codePath; 10676 final File codeFile = new File(codePath); 10677 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 10678 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 10679 10680 info.nativeLibraryRootDir = null; 10681 info.nativeLibraryRootRequiresIsa = false; 10682 info.nativeLibraryDir = null; 10683 info.secondaryNativeLibraryDir = null; 10684 10685 if (isApkFile(codeFile)) { 10686 // Monolithic install 10687 if (bundledApp) { 10688 // If "/system/lib64/apkname" exists, assume that is the per-package 10689 // native library directory to use; otherwise use "/system/lib/apkname". 10690 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 10691 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 10692 getPrimaryInstructionSet(info)); 10693 10694 // This is a bundled system app so choose the path based on the ABI. 10695 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 10696 // is just the default path. 10697 final String apkName = deriveCodePathName(codePath); 10698 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 10699 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 10700 apkName).getAbsolutePath(); 10701 10702 if (info.secondaryCpuAbi != null) { 10703 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 10704 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 10705 secondaryLibDir, apkName).getAbsolutePath(); 10706 } 10707 } else if (asecApp) { 10708 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 10709 .getAbsolutePath(); 10710 } else { 10711 final String apkName = deriveCodePathName(codePath); 10712 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName) 10713 .getAbsolutePath(); 10714 } 10715 10716 info.nativeLibraryRootRequiresIsa = false; 10717 info.nativeLibraryDir = info.nativeLibraryRootDir; 10718 } else { 10719 // Cluster install 10720 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 10721 info.nativeLibraryRootRequiresIsa = true; 10722 10723 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 10724 getPrimaryInstructionSet(info)).getAbsolutePath(); 10725 10726 if (info.secondaryCpuAbi != null) { 10727 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 10728 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 10729 } 10730 } 10731 } 10732 10733 /** 10734 * Calculate the abis and roots for a bundled app. These can uniquely 10735 * be determined from the contents of the system partition, i.e whether 10736 * it contains 64 or 32 bit shared libraries etc. We do not validate any 10737 * of this information, and instead assume that the system was built 10738 * sensibly. 10739 */ 10740 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg, 10741 PackageSetting pkgSetting) { 10742 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 10743 10744 // If "/system/lib64/apkname" exists, assume that is the per-package 10745 // native library directory to use; otherwise use "/system/lib/apkname". 10746 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 10747 setBundledAppAbi(pkg, apkRoot, apkName); 10748 // pkgSetting might be null during rescan following uninstall of updates 10749 // to a bundled app, so accommodate that possibility. The settings in 10750 // that case will be established later from the parsed package. 10751 // 10752 // If the settings aren't null, sync them up with what we've just derived. 10753 // note that apkRoot isn't stored in the package settings. 10754 if (pkgSetting != null) { 10755 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 10756 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 10757 } 10758 } 10759 10760 /** 10761 * Deduces the ABI of a bundled app and sets the relevant fields on the 10762 * parsed pkg object. 10763 * 10764 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 10765 * under which system libraries are installed. 10766 * @param apkName the name of the installed package. 10767 */ 10768 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 10769 final File codeFile = new File(pkg.codePath); 10770 10771 final boolean has64BitLibs; 10772 final boolean has32BitLibs; 10773 if (isApkFile(codeFile)) { 10774 // Monolithic install 10775 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 10776 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 10777 } else { 10778 // Cluster install 10779 final File rootDir = new File(codeFile, LIB_DIR_NAME); 10780 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 10781 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 10782 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 10783 has64BitLibs = (new File(rootDir, isa)).exists(); 10784 } else { 10785 has64BitLibs = false; 10786 } 10787 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 10788 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 10789 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 10790 has32BitLibs = (new File(rootDir, isa)).exists(); 10791 } else { 10792 has32BitLibs = false; 10793 } 10794 } 10795 10796 if (has64BitLibs && !has32BitLibs) { 10797 // The package has 64 bit libs, but not 32 bit libs. Its primary 10798 // ABI should be 64 bit. We can safely assume here that the bundled 10799 // native libraries correspond to the most preferred ABI in the list. 10800 10801 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10802 pkg.applicationInfo.secondaryCpuAbi = null; 10803 } else if (has32BitLibs && !has64BitLibs) { 10804 // The package has 32 bit libs but not 64 bit libs. Its primary 10805 // ABI should be 32 bit. 10806 10807 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10808 pkg.applicationInfo.secondaryCpuAbi = null; 10809 } else if (has32BitLibs && has64BitLibs) { 10810 // The application has both 64 and 32 bit bundled libraries. We check 10811 // here that the app declares multiArch support, and warn if it doesn't. 10812 // 10813 // We will be lenient here and record both ABIs. The primary will be the 10814 // ABI that's higher on the list, i.e, a device that's configured to prefer 10815 // 64 bit apps will see a 64 bit primary ABI, 10816 10817 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 10818 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 10819 } 10820 10821 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 10822 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10823 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10824 } else { 10825 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10826 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10827 } 10828 } else { 10829 pkg.applicationInfo.primaryCpuAbi = null; 10830 pkg.applicationInfo.secondaryCpuAbi = null; 10831 } 10832 } 10833 10834 private void killApplication(String pkgName, int appId, String reason) { 10835 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 10836 } 10837 10838 private void killApplication(String pkgName, int appId, int userId, String reason) { 10839 // Request the ActivityManager to kill the process(only for existing packages) 10840 // so that we do not end up in a confused state while the user is still using the older 10841 // version of the application while the new one gets installed. 10842 final long token = Binder.clearCallingIdentity(); 10843 try { 10844 IActivityManager am = ActivityManager.getService(); 10845 if (am != null) { 10846 try { 10847 am.killApplication(pkgName, appId, userId, reason); 10848 } catch (RemoteException e) { 10849 } 10850 } 10851 } finally { 10852 Binder.restoreCallingIdentity(token); 10853 } 10854 } 10855 10856 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 10857 // Remove the parent package setting 10858 PackageSetting ps = (PackageSetting) pkg.mExtras; 10859 if (ps != null) { 10860 removePackageLI(ps, chatty); 10861 } 10862 // Remove the child package setting 10863 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10864 for (int i = 0; i < childCount; i++) { 10865 PackageParser.Package childPkg = pkg.childPackages.get(i); 10866 ps = (PackageSetting) childPkg.mExtras; 10867 if (ps != null) { 10868 removePackageLI(ps, chatty); 10869 } 10870 } 10871 } 10872 10873 void removePackageLI(PackageSetting ps, boolean chatty) { 10874 if (DEBUG_INSTALL) { 10875 if (chatty) 10876 Log.d(TAG, "Removing package " + ps.name); 10877 } 10878 10879 // writer 10880 synchronized (mPackages) { 10881 mPackages.remove(ps.name); 10882 final PackageParser.Package pkg = ps.pkg; 10883 if (pkg != null) { 10884 cleanPackageDataStructuresLILPw(pkg, chatty); 10885 } 10886 } 10887 } 10888 10889 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 10890 if (DEBUG_INSTALL) { 10891 if (chatty) 10892 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 10893 } 10894 10895 // writer 10896 synchronized (mPackages) { 10897 // Remove the parent package 10898 mPackages.remove(pkg.applicationInfo.packageName); 10899 cleanPackageDataStructuresLILPw(pkg, chatty); 10900 10901 // Remove the child packages 10902 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10903 for (int i = 0; i < childCount; i++) { 10904 PackageParser.Package childPkg = pkg.childPackages.get(i); 10905 mPackages.remove(childPkg.applicationInfo.packageName); 10906 cleanPackageDataStructuresLILPw(childPkg, chatty); 10907 } 10908 } 10909 } 10910 10911 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 10912 int N = pkg.providers.size(); 10913 StringBuilder r = null; 10914 int i; 10915 for (i=0; i<N; i++) { 10916 PackageParser.Provider p = pkg.providers.get(i); 10917 mProviders.removeProvider(p); 10918 if (p.info.authority == null) { 10919 10920 /* There was another ContentProvider with this authority when 10921 * this app was installed so this authority is null, 10922 * Ignore it as we don't have to unregister the provider. 10923 */ 10924 continue; 10925 } 10926 String names[] = p.info.authority.split(";"); 10927 for (int j = 0; j < names.length; j++) { 10928 if (mProvidersByAuthority.get(names[j]) == p) { 10929 mProvidersByAuthority.remove(names[j]); 10930 if (DEBUG_REMOVE) { 10931 if (chatty) 10932 Log.d(TAG, "Unregistered content provider: " + names[j] 10933 + ", className = " + p.info.name + ", isSyncable = " 10934 + p.info.isSyncable); 10935 } 10936 } 10937 } 10938 if (DEBUG_REMOVE && chatty) { 10939 if (r == null) { 10940 r = new StringBuilder(256); 10941 } else { 10942 r.append(' '); 10943 } 10944 r.append(p.info.name); 10945 } 10946 } 10947 if (r != null) { 10948 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 10949 } 10950 10951 N = pkg.services.size(); 10952 r = null; 10953 for (i=0; i<N; i++) { 10954 PackageParser.Service s = pkg.services.get(i); 10955 mServices.removeService(s); 10956 if (chatty) { 10957 if (r == null) { 10958 r = new StringBuilder(256); 10959 } else { 10960 r.append(' '); 10961 } 10962 r.append(s.info.name); 10963 } 10964 } 10965 if (r != null) { 10966 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 10967 } 10968 10969 N = pkg.receivers.size(); 10970 r = null; 10971 for (i=0; i<N; i++) { 10972 PackageParser.Activity a = pkg.receivers.get(i); 10973 mReceivers.removeActivity(a, "receiver"); 10974 if (DEBUG_REMOVE && chatty) { 10975 if (r == null) { 10976 r = new StringBuilder(256); 10977 } else { 10978 r.append(' '); 10979 } 10980 r.append(a.info.name); 10981 } 10982 } 10983 if (r != null) { 10984 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 10985 } 10986 10987 N = pkg.activities.size(); 10988 r = null; 10989 for (i=0; i<N; i++) { 10990 PackageParser.Activity a = pkg.activities.get(i); 10991 mActivities.removeActivity(a, "activity"); 10992 if (DEBUG_REMOVE && chatty) { 10993 if (r == null) { 10994 r = new StringBuilder(256); 10995 } else { 10996 r.append(' '); 10997 } 10998 r.append(a.info.name); 10999 } 11000 } 11001 if (r != null) { 11002 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 11003 } 11004 11005 N = pkg.permissions.size(); 11006 r = null; 11007 for (i=0; i<N; i++) { 11008 PackageParser.Permission p = pkg.permissions.get(i); 11009 BasePermission bp = mSettings.mPermissions.get(p.info.name); 11010 if (bp == null) { 11011 bp = mSettings.mPermissionTrees.get(p.info.name); 11012 } 11013 if (bp != null && bp.perm == p) { 11014 bp.perm = null; 11015 if (DEBUG_REMOVE && chatty) { 11016 if (r == null) { 11017 r = new StringBuilder(256); 11018 } else { 11019 r.append(' '); 11020 } 11021 r.append(p.info.name); 11022 } 11023 } 11024 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11025 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 11026 if (appOpPkgs != null) { 11027 appOpPkgs.remove(pkg.packageName); 11028 } 11029 } 11030 } 11031 if (r != null) { 11032 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 11033 } 11034 11035 N = pkg.requestedPermissions.size(); 11036 r = null; 11037 for (i=0; i<N; i++) { 11038 String perm = pkg.requestedPermissions.get(i); 11039 BasePermission bp = mSettings.mPermissions.get(perm); 11040 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11041 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 11042 if (appOpPkgs != null) { 11043 appOpPkgs.remove(pkg.packageName); 11044 if (appOpPkgs.isEmpty()) { 11045 mAppOpPermissionPackages.remove(perm); 11046 } 11047 } 11048 } 11049 } 11050 if (r != null) { 11051 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 11052 } 11053 11054 N = pkg.instrumentation.size(); 11055 r = null; 11056 for (i=0; i<N; i++) { 11057 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 11058 mInstrumentation.remove(a.getComponentName()); 11059 if (DEBUG_REMOVE && chatty) { 11060 if (r == null) { 11061 r = new StringBuilder(256); 11062 } else { 11063 r.append(' '); 11064 } 11065 r.append(a.info.name); 11066 } 11067 } 11068 if (r != null) { 11069 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 11070 } 11071 11072 r = null; 11073 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11074 // Only system apps can hold shared libraries. 11075 if (pkg.libraryNames != null) { 11076 for (i = 0; i < pkg.libraryNames.size(); i++) { 11077 String name = pkg.libraryNames.get(i); 11078 if (removeSharedLibraryLPw(name, 0)) { 11079 if (DEBUG_REMOVE && chatty) { 11080 if (r == null) { 11081 r = new StringBuilder(256); 11082 } else { 11083 r.append(' '); 11084 } 11085 r.append(name); 11086 } 11087 } 11088 } 11089 } 11090 } 11091 11092 r = null; 11093 11094 // Any package can hold static shared libraries. 11095 if (pkg.staticSharedLibName != null) { 11096 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) { 11097 if (DEBUG_REMOVE && chatty) { 11098 if (r == null) { 11099 r = new StringBuilder(256); 11100 } else { 11101 r.append(' '); 11102 } 11103 r.append(pkg.staticSharedLibName); 11104 } 11105 } 11106 } 11107 11108 if (r != null) { 11109 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 11110 } 11111 } 11112 11113 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 11114 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 11115 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 11116 return true; 11117 } 11118 } 11119 return false; 11120 } 11121 11122 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 11123 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 11124 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 11125 11126 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 11127 // Update the parent permissions 11128 updatePermissionsLPw(pkg.packageName, pkg, flags); 11129 // Update the child permissions 11130 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 11131 for (int i = 0; i < childCount; i++) { 11132 PackageParser.Package childPkg = pkg.childPackages.get(i); 11133 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 11134 } 11135 } 11136 11137 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 11138 int flags) { 11139 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 11140 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 11141 } 11142 11143 private void updatePermissionsLPw(String changingPkg, 11144 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 11145 // Make sure there are no dangling permission trees. 11146 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 11147 while (it.hasNext()) { 11148 final BasePermission bp = it.next(); 11149 if (bp.packageSetting == null) { 11150 // We may not yet have parsed the package, so just see if 11151 // we still know about its settings. 11152 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 11153 } 11154 if (bp.packageSetting == null) { 11155 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 11156 + " from package " + bp.sourcePackage); 11157 it.remove(); 11158 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 11159 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 11160 Slog.i(TAG, "Removing old permission tree: " + bp.name 11161 + " from package " + bp.sourcePackage); 11162 flags |= UPDATE_PERMISSIONS_ALL; 11163 it.remove(); 11164 } 11165 } 11166 } 11167 11168 // Make sure all dynamic permissions have been assigned to a package, 11169 // and make sure there are no dangling permissions. 11170 it = mSettings.mPermissions.values().iterator(); 11171 while (it.hasNext()) { 11172 final BasePermission bp = it.next(); 11173 if (bp.type == BasePermission.TYPE_DYNAMIC) { 11174 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 11175 + bp.name + " pkg=" + bp.sourcePackage 11176 + " info=" + bp.pendingInfo); 11177 if (bp.packageSetting == null && bp.pendingInfo != null) { 11178 final BasePermission tree = findPermissionTreeLP(bp.name); 11179 if (tree != null && tree.perm != null) { 11180 bp.packageSetting = tree.packageSetting; 11181 bp.perm = new PackageParser.Permission(tree.perm.owner, 11182 new PermissionInfo(bp.pendingInfo)); 11183 bp.perm.info.packageName = tree.perm.info.packageName; 11184 bp.perm.info.name = bp.name; 11185 bp.uid = tree.uid; 11186 } 11187 } 11188 } 11189 if (bp.packageSetting == null) { 11190 // We may not yet have parsed the package, so just see if 11191 // we still know about its settings. 11192 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 11193 } 11194 if (bp.packageSetting == null) { 11195 Slog.w(TAG, "Removing dangling permission: " + bp.name 11196 + " from package " + bp.sourcePackage); 11197 it.remove(); 11198 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 11199 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 11200 Slog.i(TAG, "Removing old permission: " + bp.name 11201 + " from package " + bp.sourcePackage); 11202 flags |= UPDATE_PERMISSIONS_ALL; 11203 it.remove(); 11204 } 11205 } 11206 } 11207 11208 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 11209 // Now update the permissions for all packages, in particular 11210 // replace the granted permissions of the system packages. 11211 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 11212 for (PackageParser.Package pkg : mPackages.values()) { 11213 if (pkg != pkgInfo) { 11214 // Only replace for packages on requested volume 11215 final String volumeUuid = getVolumeUuidForPackage(pkg); 11216 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 11217 && Objects.equals(replaceVolumeUuid, volumeUuid); 11218 grantPermissionsLPw(pkg, replace, changingPkg); 11219 } 11220 } 11221 } 11222 11223 if (pkgInfo != null) { 11224 // Only replace for packages on requested volume 11225 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 11226 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 11227 && Objects.equals(replaceVolumeUuid, volumeUuid); 11228 grantPermissionsLPw(pkgInfo, replace, changingPkg); 11229 } 11230 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 11231 } 11232 11233 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 11234 String packageOfInterest) { 11235 // IMPORTANT: There are two types of permissions: install and runtime. 11236 // Install time permissions are granted when the app is installed to 11237 // all device users and users added in the future. Runtime permissions 11238 // are granted at runtime explicitly to specific users. Normal and signature 11239 // protected permissions are install time permissions. Dangerous permissions 11240 // are install permissions if the app's target SDK is Lollipop MR1 or older, 11241 // otherwise they are runtime permissions. This function does not manage 11242 // runtime permissions except for the case an app targeting Lollipop MR1 11243 // being upgraded to target a newer SDK, in which case dangerous permissions 11244 // are transformed from install time to runtime ones. 11245 11246 final PackageSetting ps = (PackageSetting) pkg.mExtras; 11247 if (ps == null) { 11248 return; 11249 } 11250 11251 PermissionsState permissionsState = ps.getPermissionsState(); 11252 PermissionsState origPermissions = permissionsState; 11253 11254 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 11255 11256 boolean runtimePermissionsRevoked = false; 11257 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 11258 11259 boolean changedInstallPermission = false; 11260 11261 if (replace) { 11262 ps.installPermissionsFixed = false; 11263 if (!ps.isSharedUser()) { 11264 origPermissions = new PermissionsState(permissionsState); 11265 permissionsState.reset(); 11266 } else { 11267 // We need to know only about runtime permission changes since the 11268 // calling code always writes the install permissions state but 11269 // the runtime ones are written only if changed. The only cases of 11270 // changed runtime permissions here are promotion of an install to 11271 // runtime and revocation of a runtime from a shared user. 11272 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 11273 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 11274 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 11275 runtimePermissionsRevoked = true; 11276 } 11277 } 11278 } 11279 11280 permissionsState.setGlobalGids(mGlobalGids); 11281 11282 final int N = pkg.requestedPermissions.size(); 11283 for (int i=0; i<N; i++) { 11284 final String name = pkg.requestedPermissions.get(i); 11285 final BasePermission bp = mSettings.mPermissions.get(name); 11286 11287 if (DEBUG_INSTALL) { 11288 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 11289 } 11290 11291 if (bp == null || bp.packageSetting == null) { 11292 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 11293 Slog.w(TAG, "Unknown permission " + name 11294 + " in package " + pkg.packageName); 11295 } 11296 continue; 11297 } 11298 11299 11300 // Limit ephemeral apps to ephemeral allowed permissions. 11301 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) { 11302 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package " 11303 + pkg.packageName); 11304 continue; 11305 } 11306 11307 final String perm = bp.name; 11308 boolean allowedSig = false; 11309 int grant = GRANT_DENIED; 11310 11311 // Keep track of app op permissions. 11312 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11313 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 11314 if (pkgs == null) { 11315 pkgs = new ArraySet<>(); 11316 mAppOpPermissionPackages.put(bp.name, pkgs); 11317 } 11318 pkgs.add(pkg.packageName); 11319 } 11320 11321 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 11322 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 11323 >= Build.VERSION_CODES.M; 11324 switch (level) { 11325 case PermissionInfo.PROTECTION_NORMAL: { 11326 // For all apps normal permissions are install time ones. 11327 grant = GRANT_INSTALL; 11328 } break; 11329 11330 case PermissionInfo.PROTECTION_DANGEROUS: { 11331 // If a permission review is required for legacy apps we represent 11332 // their permissions as always granted runtime ones since we need 11333 // to keep the review required permission flag per user while an 11334 // install permission's state is shared across all users. 11335 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) { 11336 // For legacy apps dangerous permissions are install time ones. 11337 grant = GRANT_INSTALL; 11338 } else if (origPermissions.hasInstallPermission(bp.name)) { 11339 // For legacy apps that became modern, install becomes runtime. 11340 grant = GRANT_UPGRADE; 11341 } else if (mPromoteSystemApps 11342 && isSystemApp(ps) 11343 && mExistingSystemPackages.contains(ps.name)) { 11344 // For legacy system apps, install becomes runtime. 11345 // We cannot check hasInstallPermission() for system apps since those 11346 // permissions were granted implicitly and not persisted pre-M. 11347 grant = GRANT_UPGRADE; 11348 } else { 11349 // For modern apps keep runtime permissions unchanged. 11350 grant = GRANT_RUNTIME; 11351 } 11352 } break; 11353 11354 case PermissionInfo.PROTECTION_SIGNATURE: { 11355 // For all apps signature permissions are install time ones. 11356 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 11357 if (allowedSig) { 11358 grant = GRANT_INSTALL; 11359 } 11360 } break; 11361 } 11362 11363 if (DEBUG_INSTALL) { 11364 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 11365 } 11366 11367 if (grant != GRANT_DENIED) { 11368 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 11369 // If this is an existing, non-system package, then 11370 // we can't add any new permissions to it. 11371 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 11372 // Except... if this is a permission that was added 11373 // to the platform (note: need to only do this when 11374 // updating the platform). 11375 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 11376 grant = GRANT_DENIED; 11377 } 11378 } 11379 } 11380 11381 switch (grant) { 11382 case GRANT_INSTALL: { 11383 // Revoke this as runtime permission to handle the case of 11384 // a runtime permission being downgraded to an install one. 11385 // Also in permission review mode we keep dangerous permissions 11386 // for legacy apps 11387 for (int userId : UserManagerService.getInstance().getUserIds()) { 11388 if (origPermissions.getRuntimePermissionState( 11389 bp.name, userId) != null) { 11390 // Revoke the runtime permission and clear the flags. 11391 origPermissions.revokeRuntimePermission(bp, userId); 11392 origPermissions.updatePermissionFlags(bp, userId, 11393 PackageManager.MASK_PERMISSION_FLAGS, 0); 11394 // If we revoked a permission permission, we have to write. 11395 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11396 changedRuntimePermissionUserIds, userId); 11397 } 11398 } 11399 // Grant an install permission. 11400 if (permissionsState.grantInstallPermission(bp) != 11401 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11402 changedInstallPermission = true; 11403 } 11404 } break; 11405 11406 case GRANT_RUNTIME: { 11407 // Grant previously granted runtime permissions. 11408 for (int userId : UserManagerService.getInstance().getUserIds()) { 11409 PermissionState permissionState = origPermissions 11410 .getRuntimePermissionState(bp.name, userId); 11411 int flags = permissionState != null 11412 ? permissionState.getFlags() : 0; 11413 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 11414 // Don't propagate the permission in a permission review mode if 11415 // the former was revoked, i.e. marked to not propagate on upgrade. 11416 // Note that in a permission review mode install permissions are 11417 // represented as constantly granted runtime ones since we need to 11418 // keep a per user state associated with the permission. Also the 11419 // revoke on upgrade flag is no longer applicable and is reset. 11420 final boolean revokeOnUpgrade = (flags & PackageManager 11421 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 11422 if (revokeOnUpgrade) { 11423 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 11424 // Since we changed the flags, we have to write. 11425 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11426 changedRuntimePermissionUserIds, userId); 11427 } 11428 if (!mPermissionReviewRequired || !revokeOnUpgrade) { 11429 if (permissionsState.grantRuntimePermission(bp, userId) == 11430 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11431 // If we cannot put the permission as it was, 11432 // we have to write. 11433 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11434 changedRuntimePermissionUserIds, userId); 11435 } 11436 } 11437 11438 // If the app supports runtime permissions no need for a review. 11439 if (mPermissionReviewRequired 11440 && appSupportsRuntimePermissions 11441 && (flags & PackageManager 11442 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 11443 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 11444 // Since we changed the flags, we have to write. 11445 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11446 changedRuntimePermissionUserIds, userId); 11447 } 11448 } else if (mPermissionReviewRequired 11449 && !appSupportsRuntimePermissions) { 11450 // For legacy apps that need a permission review, every new 11451 // runtime permission is granted but it is pending a review. 11452 // We also need to review only platform defined runtime 11453 // permissions as these are the only ones the platform knows 11454 // how to disable the API to simulate revocation as legacy 11455 // apps don't expect to run with revoked permissions. 11456 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 11457 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 11458 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 11459 // We changed the flags, hence have to write. 11460 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11461 changedRuntimePermissionUserIds, userId); 11462 } 11463 } 11464 if (permissionsState.grantRuntimePermission(bp, userId) 11465 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 11466 // We changed the permission, hence have to write. 11467 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11468 changedRuntimePermissionUserIds, userId); 11469 } 11470 } 11471 // Propagate the permission flags. 11472 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 11473 } 11474 } break; 11475 11476 case GRANT_UPGRADE: { 11477 // Grant runtime permissions for a previously held install permission. 11478 PermissionState permissionState = origPermissions 11479 .getInstallPermissionState(bp.name); 11480 final int flags = permissionState != null ? permissionState.getFlags() : 0; 11481 11482 if (origPermissions.revokeInstallPermission(bp) 11483 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 11484 // We will be transferring the permission flags, so clear them. 11485 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 11486 PackageManager.MASK_PERMISSION_FLAGS, 0); 11487 changedInstallPermission = true; 11488 } 11489 11490 // If the permission is not to be promoted to runtime we ignore it and 11491 // also its other flags as they are not applicable to install permissions. 11492 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 11493 for (int userId : currentUserIds) { 11494 if (permissionsState.grantRuntimePermission(bp, userId) != 11495 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11496 // Transfer the permission flags. 11497 permissionsState.updatePermissionFlags(bp, userId, 11498 flags, flags); 11499 // If we granted the permission, we have to write. 11500 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11501 changedRuntimePermissionUserIds, userId); 11502 } 11503 } 11504 } 11505 } break; 11506 11507 default: { 11508 if (packageOfInterest == null 11509 || packageOfInterest.equals(pkg.packageName)) { 11510 Slog.w(TAG, "Not granting permission " + perm 11511 + " to package " + pkg.packageName 11512 + " because it was previously installed without"); 11513 } 11514 } break; 11515 } 11516 } else { 11517 if (permissionsState.revokeInstallPermission(bp) != 11518 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11519 // Also drop the permission flags. 11520 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 11521 PackageManager.MASK_PERMISSION_FLAGS, 0); 11522 changedInstallPermission = true; 11523 Slog.i(TAG, "Un-granting permission " + perm 11524 + " from package " + pkg.packageName 11525 + " (protectionLevel=" + bp.protectionLevel 11526 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 11527 + ")"); 11528 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 11529 // Don't print warning for app op permissions, since it is fine for them 11530 // not to be granted, there is a UI for the user to decide. 11531 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 11532 Slog.w(TAG, "Not granting permission " + perm 11533 + " to package " + pkg.packageName 11534 + " (protectionLevel=" + bp.protectionLevel 11535 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 11536 + ")"); 11537 } 11538 } 11539 } 11540 } 11541 11542 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 11543 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 11544 // This is the first that we have heard about this package, so the 11545 // permissions we have now selected are fixed until explicitly 11546 // changed. 11547 ps.installPermissionsFixed = true; 11548 } 11549 11550 // Persist the runtime permissions state for users with changes. If permissions 11551 // were revoked because no app in the shared user declares them we have to 11552 // write synchronously to avoid losing runtime permissions state. 11553 for (int userId : changedRuntimePermissionUserIds) { 11554 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 11555 } 11556 } 11557 11558 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 11559 boolean allowed = false; 11560 final int NP = PackageParser.NEW_PERMISSIONS.length; 11561 for (int ip=0; ip<NP; ip++) { 11562 final PackageParser.NewPermissionInfo npi 11563 = PackageParser.NEW_PERMISSIONS[ip]; 11564 if (npi.name.equals(perm) 11565 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 11566 allowed = true; 11567 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 11568 + pkg.packageName); 11569 break; 11570 } 11571 } 11572 return allowed; 11573 } 11574 11575 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 11576 BasePermission bp, PermissionsState origPermissions) { 11577 boolean privilegedPermission = (bp.protectionLevel 11578 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0; 11579 boolean privappPermissionsDisable = 11580 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE; 11581 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage); 11582 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName); 11583 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp() 11584 && !platformPackage && platformPermission) { 11585 ArraySet<String> wlPermissions = SystemConfig.getInstance() 11586 .getPrivAppPermissions(pkg.packageName); 11587 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm); 11588 if (!whitelisted) { 11589 Slog.w(TAG, "Privileged permission " + perm + " for package " 11590 + pkg.packageName + " - not in privapp-permissions whitelist"); 11591 // Only report violations for apps on system image 11592 if (!mSystemReady && !pkg.isUpdatedSystemApp()) { 11593 if (mPrivappPermissionsViolations == null) { 11594 mPrivappPermissionsViolations = new ArraySet<>(); 11595 } 11596 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm); 11597 } 11598 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { 11599 return false; 11600 } 11601 } 11602 } 11603 boolean allowed = (compareSignatures( 11604 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 11605 == PackageManager.SIGNATURE_MATCH) 11606 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 11607 == PackageManager.SIGNATURE_MATCH); 11608 if (!allowed && privilegedPermission) { 11609 if (isSystemApp(pkg)) { 11610 // For updated system applications, a system permission 11611 // is granted only if it had been defined by the original application. 11612 if (pkg.isUpdatedSystemApp()) { 11613 final PackageSetting sysPs = mSettings 11614 .getDisabledSystemPkgLPr(pkg.packageName); 11615 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 11616 // If the original was granted this permission, we take 11617 // that grant decision as read and propagate it to the 11618 // update. 11619 if (sysPs.isPrivileged()) { 11620 allowed = true; 11621 } 11622 } else { 11623 // The system apk may have been updated with an older 11624 // version of the one on the data partition, but which 11625 // granted a new system permission that it didn't have 11626 // before. In this case we do want to allow the app to 11627 // now get the new permission if the ancestral apk is 11628 // privileged to get it. 11629 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 11630 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 11631 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 11632 allowed = true; 11633 break; 11634 } 11635 } 11636 } 11637 // Also if a privileged parent package on the system image or any of 11638 // its children requested a privileged permission, the updated child 11639 // packages can also get the permission. 11640 if (pkg.parentPackage != null) { 11641 final PackageSetting disabledSysParentPs = mSettings 11642 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 11643 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 11644 && disabledSysParentPs.isPrivileged()) { 11645 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 11646 allowed = true; 11647 } else if (disabledSysParentPs.pkg.childPackages != null) { 11648 final int count = disabledSysParentPs.pkg.childPackages.size(); 11649 for (int i = 0; i < count; i++) { 11650 PackageParser.Package disabledSysChildPkg = 11651 disabledSysParentPs.pkg.childPackages.get(i); 11652 if (isPackageRequestingPermission(disabledSysChildPkg, 11653 perm)) { 11654 allowed = true; 11655 break; 11656 } 11657 } 11658 } 11659 } 11660 } 11661 } 11662 } else { 11663 allowed = isPrivilegedApp(pkg); 11664 } 11665 } 11666 } 11667 if (!allowed) { 11668 if (!allowed && (bp.protectionLevel 11669 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 11670 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 11671 // If this was a previously normal/dangerous permission that got moved 11672 // to a system permission as part of the runtime permission redesign, then 11673 // we still want to blindly grant it to old apps. 11674 allowed = true; 11675 } 11676 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 11677 && pkg.packageName.equals(mRequiredInstallerPackage)) { 11678 // If this permission is to be granted to the system installer and 11679 // this app is an installer, then it gets the permission. 11680 allowed = true; 11681 } 11682 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 11683 && pkg.packageName.equals(mRequiredVerifierPackage)) { 11684 // If this permission is to be granted to the system verifier and 11685 // this app is a verifier, then it gets the permission. 11686 allowed = true; 11687 } 11688 if (!allowed && (bp.protectionLevel 11689 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 11690 && isSystemApp(pkg)) { 11691 // Any pre-installed system app is allowed to get this permission. 11692 allowed = true; 11693 } 11694 if (!allowed && (bp.protectionLevel 11695 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 11696 // For development permissions, a development permission 11697 // is granted only if it was already granted. 11698 allowed = origPermissions.hasInstallPermission(perm); 11699 } 11700 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 11701 && pkg.packageName.equals(mSetupWizardPackage)) { 11702 // If this permission is to be granted to the system setup wizard and 11703 // this app is a setup wizard, then it gets the permission. 11704 allowed = true; 11705 } 11706 } 11707 return allowed; 11708 } 11709 11710 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 11711 final int permCount = pkg.requestedPermissions.size(); 11712 for (int j = 0; j < permCount; j++) { 11713 String requestedPermission = pkg.requestedPermissions.get(j); 11714 if (permission.equals(requestedPermission)) { 11715 return true; 11716 } 11717 } 11718 return false; 11719 } 11720 11721 final class ActivityIntentResolver 11722 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 11723 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11724 boolean defaultOnly, int userId) { 11725 if (!sUserManager.exists(userId)) return null; 11726 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0); 11727 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11728 } 11729 11730 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11731 int userId) { 11732 if (!sUserManager.exists(userId)) return null; 11733 mFlags = flags; 11734 return super.queryIntent(intent, resolvedType, 11735 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 11736 userId); 11737 } 11738 11739 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11740 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 11741 if (!sUserManager.exists(userId)) return null; 11742 if (packageActivities == null) { 11743 return null; 11744 } 11745 mFlags = flags; 11746 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11747 final int N = packageActivities.size(); 11748 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 11749 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 11750 11751 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 11752 for (int i = 0; i < N; ++i) { 11753 intentFilters = packageActivities.get(i).intents; 11754 if (intentFilters != null && intentFilters.size() > 0) { 11755 PackageParser.ActivityIntentInfo[] array = 11756 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 11757 intentFilters.toArray(array); 11758 listCut.add(array); 11759 } 11760 } 11761 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11762 } 11763 11764 /** 11765 * Finds a privileged activity that matches the specified activity names. 11766 */ 11767 private PackageParser.Activity findMatchingActivity( 11768 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 11769 for (PackageParser.Activity sysActivity : activityList) { 11770 if (sysActivity.info.name.equals(activityInfo.name)) { 11771 return sysActivity; 11772 } 11773 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 11774 return sysActivity; 11775 } 11776 if (sysActivity.info.targetActivity != null) { 11777 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 11778 return sysActivity; 11779 } 11780 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 11781 return sysActivity; 11782 } 11783 } 11784 } 11785 return null; 11786 } 11787 11788 public class IterGenerator<E> { 11789 public Iterator<E> generate(ActivityIntentInfo info) { 11790 return null; 11791 } 11792 } 11793 11794 public class ActionIterGenerator extends IterGenerator<String> { 11795 @Override 11796 public Iterator<String> generate(ActivityIntentInfo info) { 11797 return info.actionsIterator(); 11798 } 11799 } 11800 11801 public class CategoriesIterGenerator extends IterGenerator<String> { 11802 @Override 11803 public Iterator<String> generate(ActivityIntentInfo info) { 11804 return info.categoriesIterator(); 11805 } 11806 } 11807 11808 public class SchemesIterGenerator extends IterGenerator<String> { 11809 @Override 11810 public Iterator<String> generate(ActivityIntentInfo info) { 11811 return info.schemesIterator(); 11812 } 11813 } 11814 11815 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 11816 @Override 11817 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 11818 return info.authoritiesIterator(); 11819 } 11820 } 11821 11822 /** 11823 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 11824 * MODIFIED. Do not pass in a list that should not be changed. 11825 */ 11826 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 11827 IterGenerator<T> generator, Iterator<T> searchIterator) { 11828 // loop through the set of actions; every one must be found in the intent filter 11829 while (searchIterator.hasNext()) { 11830 // we must have at least one filter in the list to consider a match 11831 if (intentList.size() == 0) { 11832 break; 11833 } 11834 11835 final T searchAction = searchIterator.next(); 11836 11837 // loop through the set of intent filters 11838 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 11839 while (intentIter.hasNext()) { 11840 final ActivityIntentInfo intentInfo = intentIter.next(); 11841 boolean selectionFound = false; 11842 11843 // loop through the intent filter's selection criteria; at least one 11844 // of them must match the searched criteria 11845 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 11846 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 11847 final T intentSelection = intentSelectionIter.next(); 11848 if (intentSelection != null && intentSelection.equals(searchAction)) { 11849 selectionFound = true; 11850 break; 11851 } 11852 } 11853 11854 // the selection criteria wasn't found in this filter's set; this filter 11855 // is not a potential match 11856 if (!selectionFound) { 11857 intentIter.remove(); 11858 } 11859 } 11860 } 11861 } 11862 11863 private boolean isProtectedAction(ActivityIntentInfo filter) { 11864 final Iterator<String> actionsIter = filter.actionsIterator(); 11865 while (actionsIter != null && actionsIter.hasNext()) { 11866 final String filterAction = actionsIter.next(); 11867 if (PROTECTED_ACTIONS.contains(filterAction)) { 11868 return true; 11869 } 11870 } 11871 return false; 11872 } 11873 11874 /** 11875 * Adjusts the priority of the given intent filter according to policy. 11876 * <p> 11877 * <ul> 11878 * <li>The priority for non privileged applications is capped to '0'</li> 11879 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 11880 * <li>The priority for unbundled updates to privileged applications is capped to the 11881 * priority defined on the system partition</li> 11882 * </ul> 11883 * <p> 11884 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 11885 * allowed to obtain any priority on any action. 11886 */ 11887 private void adjustPriority( 11888 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 11889 // nothing to do; priority is fine as-is 11890 if (intent.getPriority() <= 0) { 11891 return; 11892 } 11893 11894 final ActivityInfo activityInfo = intent.activity.info; 11895 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 11896 11897 final boolean privilegedApp = 11898 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 11899 if (!privilegedApp) { 11900 // non-privileged applications can never define a priority >0 11901 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 11902 + " package: " + applicationInfo.packageName 11903 + " activity: " + intent.activity.className 11904 + " origPrio: " + intent.getPriority()); 11905 intent.setPriority(0); 11906 return; 11907 } 11908 11909 if (systemActivities == null) { 11910 // the system package is not disabled; we're parsing the system partition 11911 if (isProtectedAction(intent)) { 11912 if (mDeferProtectedFilters) { 11913 // We can't deal with these just yet. No component should ever obtain a 11914 // >0 priority for a protected actions, with ONE exception -- the setup 11915 // wizard. The setup wizard, however, cannot be known until we're able to 11916 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 11917 // until all intent filters have been processed. Chicken, meet egg. 11918 // Let the filter temporarily have a high priority and rectify the 11919 // priorities after all system packages have been scanned. 11920 mProtectedFilters.add(intent); 11921 if (DEBUG_FILTERS) { 11922 Slog.i(TAG, "Protected action; save for later;" 11923 + " package: " + applicationInfo.packageName 11924 + " activity: " + intent.activity.className 11925 + " origPrio: " + intent.getPriority()); 11926 } 11927 return; 11928 } else { 11929 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 11930 Slog.i(TAG, "No setup wizard;" 11931 + " All protected intents capped to priority 0"); 11932 } 11933 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 11934 if (DEBUG_FILTERS) { 11935 Slog.i(TAG, "Found setup wizard;" 11936 + " allow priority " + intent.getPriority() + ";" 11937 + " package: " + intent.activity.info.packageName 11938 + " activity: " + intent.activity.className 11939 + " priority: " + intent.getPriority()); 11940 } 11941 // setup wizard gets whatever it wants 11942 return; 11943 } 11944 Slog.w(TAG, "Protected action; cap priority to 0;" 11945 + " package: " + intent.activity.info.packageName 11946 + " activity: " + intent.activity.className 11947 + " origPrio: " + intent.getPriority()); 11948 intent.setPriority(0); 11949 return; 11950 } 11951 } 11952 // privileged apps on the system image get whatever priority they request 11953 return; 11954 } 11955 11956 // privileged app unbundled update ... try to find the same activity 11957 final PackageParser.Activity foundActivity = 11958 findMatchingActivity(systemActivities, activityInfo); 11959 if (foundActivity == null) { 11960 // this is a new activity; it cannot obtain >0 priority 11961 if (DEBUG_FILTERS) { 11962 Slog.i(TAG, "New activity; cap priority to 0;" 11963 + " package: " + applicationInfo.packageName 11964 + " activity: " + intent.activity.className 11965 + " origPrio: " + intent.getPriority()); 11966 } 11967 intent.setPriority(0); 11968 return; 11969 } 11970 11971 // found activity, now check for filter equivalence 11972 11973 // a shallow copy is enough; we modify the list, not its contents 11974 final List<ActivityIntentInfo> intentListCopy = 11975 new ArrayList<>(foundActivity.intents); 11976 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 11977 11978 // find matching action subsets 11979 final Iterator<String> actionsIterator = intent.actionsIterator(); 11980 if (actionsIterator != null) { 11981 getIntentListSubset( 11982 intentListCopy, new ActionIterGenerator(), actionsIterator); 11983 if (intentListCopy.size() == 0) { 11984 // no more intents to match; we're not equivalent 11985 if (DEBUG_FILTERS) { 11986 Slog.i(TAG, "Mismatched action; cap priority to 0;" 11987 + " package: " + applicationInfo.packageName 11988 + " activity: " + intent.activity.className 11989 + " origPrio: " + intent.getPriority()); 11990 } 11991 intent.setPriority(0); 11992 return; 11993 } 11994 } 11995 11996 // find matching category subsets 11997 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 11998 if (categoriesIterator != null) { 11999 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 12000 categoriesIterator); 12001 if (intentListCopy.size() == 0) { 12002 // no more intents to match; we're not equivalent 12003 if (DEBUG_FILTERS) { 12004 Slog.i(TAG, "Mismatched category; cap priority to 0;" 12005 + " package: " + applicationInfo.packageName 12006 + " activity: " + intent.activity.className 12007 + " origPrio: " + intent.getPriority()); 12008 } 12009 intent.setPriority(0); 12010 return; 12011 } 12012 } 12013 12014 // find matching schemes subsets 12015 final Iterator<String> schemesIterator = intent.schemesIterator(); 12016 if (schemesIterator != null) { 12017 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 12018 schemesIterator); 12019 if (intentListCopy.size() == 0) { 12020 // no more intents to match; we're not equivalent 12021 if (DEBUG_FILTERS) { 12022 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 12023 + " package: " + applicationInfo.packageName 12024 + " activity: " + intent.activity.className 12025 + " origPrio: " + intent.getPriority()); 12026 } 12027 intent.setPriority(0); 12028 return; 12029 } 12030 } 12031 12032 // find matching authorities subsets 12033 final Iterator<IntentFilter.AuthorityEntry> 12034 authoritiesIterator = intent.authoritiesIterator(); 12035 if (authoritiesIterator != null) { 12036 getIntentListSubset(intentListCopy, 12037 new AuthoritiesIterGenerator(), 12038 authoritiesIterator); 12039 if (intentListCopy.size() == 0) { 12040 // no more intents to match; we're not equivalent 12041 if (DEBUG_FILTERS) { 12042 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 12043 + " package: " + applicationInfo.packageName 12044 + " activity: " + intent.activity.className 12045 + " origPrio: " + intent.getPriority()); 12046 } 12047 intent.setPriority(0); 12048 return; 12049 } 12050 } 12051 12052 // we found matching filter(s); app gets the max priority of all intents 12053 int cappedPriority = 0; 12054 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 12055 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 12056 } 12057 if (intent.getPriority() > cappedPriority) { 12058 if (DEBUG_FILTERS) { 12059 Slog.i(TAG, "Found matching filter(s);" 12060 + " cap priority to " + cappedPriority + ";" 12061 + " package: " + applicationInfo.packageName 12062 + " activity: " + intent.activity.className 12063 + " origPrio: " + intent.getPriority()); 12064 } 12065 intent.setPriority(cappedPriority); 12066 return; 12067 } 12068 // all this for nothing; the requested priority was <= what was on the system 12069 } 12070 12071 public final void addActivity(PackageParser.Activity a, String type) { 12072 mActivities.put(a.getComponentName(), a); 12073 if (DEBUG_SHOW_INFO) 12074 Log.v( 12075 TAG, " " + type + " " + 12076 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 12077 if (DEBUG_SHOW_INFO) 12078 Log.v(TAG, " Class=" + a.info.name); 12079 final int NI = a.intents.size(); 12080 for (int j=0; j<NI; j++) { 12081 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 12082 if ("activity".equals(type)) { 12083 final PackageSetting ps = 12084 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 12085 final List<PackageParser.Activity> systemActivities = 12086 ps != null && ps.pkg != null ? ps.pkg.activities : null; 12087 adjustPriority(systemActivities, intent); 12088 } 12089 if (DEBUG_SHOW_INFO) { 12090 Log.v(TAG, " IntentFilter:"); 12091 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12092 } 12093 if (!intent.debugCheck()) { 12094 Log.w(TAG, "==> For Activity " + a.info.name); 12095 } 12096 addFilter(intent); 12097 } 12098 } 12099 12100 public final void removeActivity(PackageParser.Activity a, String type) { 12101 mActivities.remove(a.getComponentName()); 12102 if (DEBUG_SHOW_INFO) { 12103 Log.v(TAG, " " + type + " " 12104 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 12105 : a.info.name) + ":"); 12106 Log.v(TAG, " Class=" + a.info.name); 12107 } 12108 final int NI = a.intents.size(); 12109 for (int j=0; j<NI; j++) { 12110 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 12111 if (DEBUG_SHOW_INFO) { 12112 Log.v(TAG, " IntentFilter:"); 12113 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12114 } 12115 removeFilter(intent); 12116 } 12117 } 12118 12119 @Override 12120 protected boolean allowFilterResult( 12121 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 12122 ActivityInfo filterAi = filter.activity.info; 12123 for (int i=dest.size()-1; i>=0; i--) { 12124 ActivityInfo destAi = dest.get(i).activityInfo; 12125 if (destAi.name == filterAi.name 12126 && destAi.packageName == filterAi.packageName) { 12127 return false; 12128 } 12129 } 12130 return true; 12131 } 12132 12133 @Override 12134 protected ActivityIntentInfo[] newArray(int size) { 12135 return new ActivityIntentInfo[size]; 12136 } 12137 12138 @Override 12139 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 12140 if (!sUserManager.exists(userId)) return true; 12141 PackageParser.Package p = filter.activity.owner; 12142 if (p != null) { 12143 PackageSetting ps = (PackageSetting)p.mExtras; 12144 if (ps != null) { 12145 // System apps are never considered stopped for purposes of 12146 // filtering, because there may be no way for the user to 12147 // actually re-launch them. 12148 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 12149 && ps.getStopped(userId); 12150 } 12151 } 12152 return false; 12153 } 12154 12155 @Override 12156 protected boolean isPackageForFilter(String packageName, 12157 PackageParser.ActivityIntentInfo info) { 12158 return packageName.equals(info.activity.owner.packageName); 12159 } 12160 12161 @Override 12162 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 12163 int match, int userId) { 12164 if (!sUserManager.exists(userId)) return null; 12165 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 12166 return null; 12167 } 12168 final PackageParser.Activity activity = info.activity; 12169 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 12170 if (ps == null) { 12171 return null; 12172 } 12173 final PackageUserState userState = ps.readUserState(userId); 12174 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 12175 userState, userId); 12176 if (ai == null) { 12177 return null; 12178 } 12179 final boolean matchVisibleToInstantApp = 12180 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; 12181 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0; 12182 // throw out filters that aren't visible to ephemeral apps 12183 if (matchVisibleToInstantApp 12184 && !(info.isVisibleToInstantApp() || userState.instantApp)) { 12185 return null; 12186 } 12187 // throw out ephemeral filters if we're not explicitly requesting them 12188 if (!isInstantApp && userState.instantApp) { 12189 return null; 12190 } 12191 final ResolveInfo res = new ResolveInfo(); 12192 res.activityInfo = ai; 12193 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 12194 res.filter = info; 12195 } 12196 if (info != null) { 12197 res.handleAllWebDataURI = info.handleAllWebDataURI(); 12198 } 12199 res.priority = info.getPriority(); 12200 res.preferredOrder = activity.owner.mPreferredOrder; 12201 //System.out.println("Result: " + res.activityInfo.className + 12202 // " = " + res.priority); 12203 res.match = match; 12204 res.isDefault = info.hasDefault; 12205 res.labelRes = info.labelRes; 12206 res.nonLocalizedLabel = info.nonLocalizedLabel; 12207 if (userNeedsBadging(userId)) { 12208 res.noResourceId = true; 12209 } else { 12210 res.icon = info.icon; 12211 } 12212 res.iconResourceId = info.icon; 12213 res.system = res.activityInfo.applicationInfo.isSystemApp(); 12214 res.instantAppAvailable = userState.instantApp; 12215 return res; 12216 } 12217 12218 @Override 12219 protected void sortResults(List<ResolveInfo> results) { 12220 Collections.sort(results, mResolvePrioritySorter); 12221 } 12222 12223 @Override 12224 protected void dumpFilter(PrintWriter out, String prefix, 12225 PackageParser.ActivityIntentInfo filter) { 12226 out.print(prefix); out.print( 12227 Integer.toHexString(System.identityHashCode(filter.activity))); 12228 out.print(' '); 12229 filter.activity.printComponentShortName(out); 12230 out.print(" filter "); 12231 out.println(Integer.toHexString(System.identityHashCode(filter))); 12232 } 12233 12234 @Override 12235 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 12236 return filter.activity; 12237 } 12238 12239 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12240 PackageParser.Activity activity = (PackageParser.Activity)label; 12241 out.print(prefix); out.print( 12242 Integer.toHexString(System.identityHashCode(activity))); 12243 out.print(' '); 12244 activity.printComponentShortName(out); 12245 if (count > 1) { 12246 out.print(" ("); out.print(count); out.print(" filters)"); 12247 } 12248 out.println(); 12249 } 12250 12251 // Keys are String (activity class name), values are Activity. 12252 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 12253 = new ArrayMap<ComponentName, PackageParser.Activity>(); 12254 private int mFlags; 12255 } 12256 12257 private final class ServiceIntentResolver 12258 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 12259 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 12260 boolean defaultOnly, int userId) { 12261 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 12262 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 12263 } 12264 12265 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 12266 int userId) { 12267 if (!sUserManager.exists(userId)) return null; 12268 mFlags = flags; 12269 return super.queryIntent(intent, resolvedType, 12270 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 12271 userId); 12272 } 12273 12274 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 12275 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 12276 if (!sUserManager.exists(userId)) return null; 12277 if (packageServices == null) { 12278 return null; 12279 } 12280 mFlags = flags; 12281 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 12282 final int N = packageServices.size(); 12283 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 12284 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 12285 12286 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 12287 for (int i = 0; i < N; ++i) { 12288 intentFilters = packageServices.get(i).intents; 12289 if (intentFilters != null && intentFilters.size() > 0) { 12290 PackageParser.ServiceIntentInfo[] array = 12291 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 12292 intentFilters.toArray(array); 12293 listCut.add(array); 12294 } 12295 } 12296 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 12297 } 12298 12299 public final void addService(PackageParser.Service s) { 12300 mServices.put(s.getComponentName(), s); 12301 if (DEBUG_SHOW_INFO) { 12302 Log.v(TAG, " " 12303 + (s.info.nonLocalizedLabel != null 12304 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 12305 Log.v(TAG, " Class=" + s.info.name); 12306 } 12307 final int NI = s.intents.size(); 12308 int j; 12309 for (j=0; j<NI; j++) { 12310 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 12311 if (DEBUG_SHOW_INFO) { 12312 Log.v(TAG, " IntentFilter:"); 12313 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12314 } 12315 if (!intent.debugCheck()) { 12316 Log.w(TAG, "==> For Service " + s.info.name); 12317 } 12318 addFilter(intent); 12319 } 12320 } 12321 12322 public final void removeService(PackageParser.Service s) { 12323 mServices.remove(s.getComponentName()); 12324 if (DEBUG_SHOW_INFO) { 12325 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 12326 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 12327 Log.v(TAG, " Class=" + s.info.name); 12328 } 12329 final int NI = s.intents.size(); 12330 int j; 12331 for (j=0; j<NI; j++) { 12332 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 12333 if (DEBUG_SHOW_INFO) { 12334 Log.v(TAG, " IntentFilter:"); 12335 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12336 } 12337 removeFilter(intent); 12338 } 12339 } 12340 12341 @Override 12342 protected boolean allowFilterResult( 12343 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 12344 ServiceInfo filterSi = filter.service.info; 12345 for (int i=dest.size()-1; i>=0; i--) { 12346 ServiceInfo destAi = dest.get(i).serviceInfo; 12347 if (destAi.name == filterSi.name 12348 && destAi.packageName == filterSi.packageName) { 12349 return false; 12350 } 12351 } 12352 return true; 12353 } 12354 12355 @Override 12356 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 12357 return new PackageParser.ServiceIntentInfo[size]; 12358 } 12359 12360 @Override 12361 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 12362 if (!sUserManager.exists(userId)) return true; 12363 PackageParser.Package p = filter.service.owner; 12364 if (p != null) { 12365 PackageSetting ps = (PackageSetting)p.mExtras; 12366 if (ps != null) { 12367 // System apps are never considered stopped for purposes of 12368 // filtering, because there may be no way for the user to 12369 // actually re-launch them. 12370 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 12371 && ps.getStopped(userId); 12372 } 12373 } 12374 return false; 12375 } 12376 12377 @Override 12378 protected boolean isPackageForFilter(String packageName, 12379 PackageParser.ServiceIntentInfo info) { 12380 return packageName.equals(info.service.owner.packageName); 12381 } 12382 12383 @Override 12384 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 12385 int match, int userId) { 12386 if (!sUserManager.exists(userId)) return null; 12387 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 12388 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 12389 return null; 12390 } 12391 final PackageParser.Service service = info.service; 12392 PackageSetting ps = (PackageSetting) service.owner.mExtras; 12393 if (ps == null) { 12394 return null; 12395 } 12396 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 12397 ps.readUserState(userId), userId); 12398 if (si == null) { 12399 return null; 12400 } 12401 final ResolveInfo res = new ResolveInfo(); 12402 res.serviceInfo = si; 12403 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 12404 res.filter = filter; 12405 } 12406 res.priority = info.getPriority(); 12407 res.preferredOrder = service.owner.mPreferredOrder; 12408 res.match = match; 12409 res.isDefault = info.hasDefault; 12410 res.labelRes = info.labelRes; 12411 res.nonLocalizedLabel = info.nonLocalizedLabel; 12412 res.icon = info.icon; 12413 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 12414 return res; 12415 } 12416 12417 @Override 12418 protected void sortResults(List<ResolveInfo> results) { 12419 Collections.sort(results, mResolvePrioritySorter); 12420 } 12421 12422 @Override 12423 protected void dumpFilter(PrintWriter out, String prefix, 12424 PackageParser.ServiceIntentInfo filter) { 12425 out.print(prefix); out.print( 12426 Integer.toHexString(System.identityHashCode(filter.service))); 12427 out.print(' '); 12428 filter.service.printComponentShortName(out); 12429 out.print(" filter "); 12430 out.println(Integer.toHexString(System.identityHashCode(filter))); 12431 } 12432 12433 @Override 12434 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 12435 return filter.service; 12436 } 12437 12438 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12439 PackageParser.Service service = (PackageParser.Service)label; 12440 out.print(prefix); out.print( 12441 Integer.toHexString(System.identityHashCode(service))); 12442 out.print(' '); 12443 service.printComponentShortName(out); 12444 if (count > 1) { 12445 out.print(" ("); out.print(count); out.print(" filters)"); 12446 } 12447 out.println(); 12448 } 12449 12450// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 12451// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 12452// final List<ResolveInfo> retList = Lists.newArrayList(); 12453// while (i.hasNext()) { 12454// final ResolveInfo resolveInfo = (ResolveInfo) i; 12455// if (isEnabledLP(resolveInfo.serviceInfo)) { 12456// retList.add(resolveInfo); 12457// } 12458// } 12459// return retList; 12460// } 12461 12462 // Keys are String (activity class name), values are Activity. 12463 private final ArrayMap<ComponentName, PackageParser.Service> mServices 12464 = new ArrayMap<ComponentName, PackageParser.Service>(); 12465 private int mFlags; 12466 } 12467 12468 private final class ProviderIntentResolver 12469 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 12470 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 12471 boolean defaultOnly, int userId) { 12472 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 12473 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 12474 } 12475 12476 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 12477 int userId) { 12478 if (!sUserManager.exists(userId)) 12479 return null; 12480 mFlags = flags; 12481 return super.queryIntent(intent, resolvedType, 12482 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 12483 userId); 12484 } 12485 12486 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 12487 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 12488 if (!sUserManager.exists(userId)) 12489 return null; 12490 if (packageProviders == null) { 12491 return null; 12492 } 12493 mFlags = flags; 12494 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 12495 final int N = packageProviders.size(); 12496 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 12497 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 12498 12499 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 12500 for (int i = 0; i < N; ++i) { 12501 intentFilters = packageProviders.get(i).intents; 12502 if (intentFilters != null && intentFilters.size() > 0) { 12503 PackageParser.ProviderIntentInfo[] array = 12504 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 12505 intentFilters.toArray(array); 12506 listCut.add(array); 12507 } 12508 } 12509 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 12510 } 12511 12512 public final void addProvider(PackageParser.Provider p) { 12513 if (mProviders.containsKey(p.getComponentName())) { 12514 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 12515 return; 12516 } 12517 12518 mProviders.put(p.getComponentName(), p); 12519 if (DEBUG_SHOW_INFO) { 12520 Log.v(TAG, " " 12521 + (p.info.nonLocalizedLabel != null 12522 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 12523 Log.v(TAG, " Class=" + p.info.name); 12524 } 12525 final int NI = p.intents.size(); 12526 int j; 12527 for (j = 0; j < NI; j++) { 12528 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 12529 if (DEBUG_SHOW_INFO) { 12530 Log.v(TAG, " IntentFilter:"); 12531 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12532 } 12533 if (!intent.debugCheck()) { 12534 Log.w(TAG, "==> For Provider " + p.info.name); 12535 } 12536 addFilter(intent); 12537 } 12538 } 12539 12540 public final void removeProvider(PackageParser.Provider p) { 12541 mProviders.remove(p.getComponentName()); 12542 if (DEBUG_SHOW_INFO) { 12543 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 12544 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 12545 Log.v(TAG, " Class=" + p.info.name); 12546 } 12547 final int NI = p.intents.size(); 12548 int j; 12549 for (j = 0; j < NI; j++) { 12550 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 12551 if (DEBUG_SHOW_INFO) { 12552 Log.v(TAG, " IntentFilter:"); 12553 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12554 } 12555 removeFilter(intent); 12556 } 12557 } 12558 12559 @Override 12560 protected boolean allowFilterResult( 12561 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 12562 ProviderInfo filterPi = filter.provider.info; 12563 for (int i = dest.size() - 1; i >= 0; i--) { 12564 ProviderInfo destPi = dest.get(i).providerInfo; 12565 if (destPi.name == filterPi.name 12566 && destPi.packageName == filterPi.packageName) { 12567 return false; 12568 } 12569 } 12570 return true; 12571 } 12572 12573 @Override 12574 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 12575 return new PackageParser.ProviderIntentInfo[size]; 12576 } 12577 12578 @Override 12579 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 12580 if (!sUserManager.exists(userId)) 12581 return true; 12582 PackageParser.Package p = filter.provider.owner; 12583 if (p != null) { 12584 PackageSetting ps = (PackageSetting) p.mExtras; 12585 if (ps != null) { 12586 // System apps are never considered stopped for purposes of 12587 // filtering, because there may be no way for the user to 12588 // actually re-launch them. 12589 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 12590 && ps.getStopped(userId); 12591 } 12592 } 12593 return false; 12594 } 12595 12596 @Override 12597 protected boolean isPackageForFilter(String packageName, 12598 PackageParser.ProviderIntentInfo info) { 12599 return packageName.equals(info.provider.owner.packageName); 12600 } 12601 12602 @Override 12603 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 12604 int match, int userId) { 12605 if (!sUserManager.exists(userId)) 12606 return null; 12607 final PackageParser.ProviderIntentInfo info = filter; 12608 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 12609 return null; 12610 } 12611 final PackageParser.Provider provider = info.provider; 12612 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 12613 if (ps == null) { 12614 return null; 12615 } 12616 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 12617 ps.readUserState(userId), userId); 12618 if (pi == null) { 12619 return null; 12620 } 12621 final ResolveInfo res = new ResolveInfo(); 12622 res.providerInfo = pi; 12623 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 12624 res.filter = filter; 12625 } 12626 res.priority = info.getPriority(); 12627 res.preferredOrder = provider.owner.mPreferredOrder; 12628 res.match = match; 12629 res.isDefault = info.hasDefault; 12630 res.labelRes = info.labelRes; 12631 res.nonLocalizedLabel = info.nonLocalizedLabel; 12632 res.icon = info.icon; 12633 res.system = res.providerInfo.applicationInfo.isSystemApp(); 12634 return res; 12635 } 12636 12637 @Override 12638 protected void sortResults(List<ResolveInfo> results) { 12639 Collections.sort(results, mResolvePrioritySorter); 12640 } 12641 12642 @Override 12643 protected void dumpFilter(PrintWriter out, String prefix, 12644 PackageParser.ProviderIntentInfo filter) { 12645 out.print(prefix); 12646 out.print( 12647 Integer.toHexString(System.identityHashCode(filter.provider))); 12648 out.print(' '); 12649 filter.provider.printComponentShortName(out); 12650 out.print(" filter "); 12651 out.println(Integer.toHexString(System.identityHashCode(filter))); 12652 } 12653 12654 @Override 12655 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 12656 return filter.provider; 12657 } 12658 12659 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12660 PackageParser.Provider provider = (PackageParser.Provider)label; 12661 out.print(prefix); out.print( 12662 Integer.toHexString(System.identityHashCode(provider))); 12663 out.print(' '); 12664 provider.printComponentShortName(out); 12665 if (count > 1) { 12666 out.print(" ("); out.print(count); out.print(" filters)"); 12667 } 12668 out.println(); 12669 } 12670 12671 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 12672 = new ArrayMap<ComponentName, PackageParser.Provider>(); 12673 private int mFlags; 12674 } 12675 12676 static final class EphemeralIntentResolver 12677 extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> { 12678 /** 12679 * The result that has the highest defined order. Ordering applies on a 12680 * per-package basis. Mapping is from package name to Pair of order and 12681 * EphemeralResolveInfo. 12682 * <p> 12683 * NOTE: This is implemented as a field variable for convenience and efficiency. 12684 * By having a field variable, we're able to track filter ordering as soon as 12685 * a non-zero order is defined. Otherwise, multiple loops across the result set 12686 * would be needed to apply ordering. If the intent resolver becomes re-entrant, 12687 * this needs to be contained entirely within {@link #filterResults}. 12688 */ 12689 final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>(); 12690 12691 @Override 12692 protected AuxiliaryResolveInfo[] newArray(int size) { 12693 return new AuxiliaryResolveInfo[size]; 12694 } 12695 12696 @Override 12697 protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) { 12698 return true; 12699 } 12700 12701 @Override 12702 protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match, 12703 int userId) { 12704 if (!sUserManager.exists(userId)) { 12705 return null; 12706 } 12707 final String packageName = responseObj.resolveInfo.getPackageName(); 12708 final Integer order = responseObj.getOrder(); 12709 final Pair<Integer, InstantAppResolveInfo> lastOrderResult = 12710 mOrderResult.get(packageName); 12711 // ordering is enabled and this item's order isn't high enough 12712 if (lastOrderResult != null && lastOrderResult.first >= order) { 12713 return null; 12714 } 12715 final InstantAppResolveInfo res = responseObj.resolveInfo; 12716 if (order > 0) { 12717 // non-zero order, enable ordering 12718 mOrderResult.put(packageName, new Pair<>(order, res)); 12719 } 12720 return responseObj; 12721 } 12722 12723 @Override 12724 protected void filterResults(List<AuxiliaryResolveInfo> results) { 12725 // only do work if ordering is enabled [most of the time it won't be] 12726 if (mOrderResult.size() == 0) { 12727 return; 12728 } 12729 int resultSize = results.size(); 12730 for (int i = 0; i < resultSize; i++) { 12731 final InstantAppResolveInfo info = results.get(i).resolveInfo; 12732 final String packageName = info.getPackageName(); 12733 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName); 12734 if (savedInfo == null) { 12735 // package doesn't having ordering 12736 continue; 12737 } 12738 if (savedInfo.second == info) { 12739 // circled back to the highest ordered item; remove from order list 12740 mOrderResult.remove(savedInfo); 12741 if (mOrderResult.size() == 0) { 12742 // no more ordered items 12743 break; 12744 } 12745 continue; 12746 } 12747 // item has a worse order, remove it from the result list 12748 results.remove(i); 12749 resultSize--; 12750 i--; 12751 } 12752 } 12753 } 12754 12755 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 12756 new Comparator<ResolveInfo>() { 12757 public int compare(ResolveInfo r1, ResolveInfo r2) { 12758 int v1 = r1.priority; 12759 int v2 = r2.priority; 12760 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 12761 if (v1 != v2) { 12762 return (v1 > v2) ? -1 : 1; 12763 } 12764 v1 = r1.preferredOrder; 12765 v2 = r2.preferredOrder; 12766 if (v1 != v2) { 12767 return (v1 > v2) ? -1 : 1; 12768 } 12769 if (r1.isDefault != r2.isDefault) { 12770 return r1.isDefault ? -1 : 1; 12771 } 12772 v1 = r1.match; 12773 v2 = r2.match; 12774 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 12775 if (v1 != v2) { 12776 return (v1 > v2) ? -1 : 1; 12777 } 12778 if (r1.system != r2.system) { 12779 return r1.system ? -1 : 1; 12780 } 12781 if (r1.activityInfo != null) { 12782 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 12783 } 12784 if (r1.serviceInfo != null) { 12785 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 12786 } 12787 if (r1.providerInfo != null) { 12788 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 12789 } 12790 return 0; 12791 } 12792 }; 12793 12794 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 12795 new Comparator<ProviderInfo>() { 12796 public int compare(ProviderInfo p1, ProviderInfo p2) { 12797 final int v1 = p1.initOrder; 12798 final int v2 = p2.initOrder; 12799 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 12800 } 12801 }; 12802 12803 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 12804 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 12805 final int[] userIds) { 12806 mHandler.post(new Runnable() { 12807 @Override 12808 public void run() { 12809 try { 12810 final IActivityManager am = ActivityManager.getService(); 12811 if (am == null) return; 12812 final int[] resolvedUserIds; 12813 if (userIds == null) { 12814 resolvedUserIds = am.getRunningUserIds(); 12815 } else { 12816 resolvedUserIds = userIds; 12817 } 12818 for (int id : resolvedUserIds) { 12819 final Intent intent = new Intent(action, 12820 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 12821 if (extras != null) { 12822 intent.putExtras(extras); 12823 } 12824 if (targetPkg != null) { 12825 intent.setPackage(targetPkg); 12826 } 12827 // Modify the UID when posting to other users 12828 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 12829 if (uid > 0 && UserHandle.getUserId(uid) != id) { 12830 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 12831 intent.putExtra(Intent.EXTRA_UID, uid); 12832 } 12833 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 12834 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 12835 if (DEBUG_BROADCASTS) { 12836 RuntimeException here = new RuntimeException("here"); 12837 here.fillInStackTrace(); 12838 Slog.d(TAG, "Sending to user " + id + ": " 12839 + intent.toShortString(false, true, false, false) 12840 + " " + intent.getExtras(), here); 12841 } 12842 am.broadcastIntent(null, intent, null, finishedReceiver, 12843 0, null, null, null, android.app.AppOpsManager.OP_NONE, 12844 null, finishedReceiver != null, false, id); 12845 } 12846 } catch (RemoteException ex) { 12847 } 12848 } 12849 }); 12850 } 12851 12852 /** 12853 * Check if the external storage media is available. This is true if there 12854 * is a mounted external storage medium or if the external storage is 12855 * emulated. 12856 */ 12857 private boolean isExternalMediaAvailable() { 12858 return mMediaMounted || Environment.isExternalStorageEmulated(); 12859 } 12860 12861 @Override 12862 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 12863 // writer 12864 synchronized (mPackages) { 12865 if (!isExternalMediaAvailable()) { 12866 // If the external storage is no longer mounted at this point, 12867 // the caller may not have been able to delete all of this 12868 // packages files and can not delete any more. Bail. 12869 return null; 12870 } 12871 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 12872 if (lastPackage != null) { 12873 pkgs.remove(lastPackage); 12874 } 12875 if (pkgs.size() > 0) { 12876 return pkgs.get(0); 12877 } 12878 } 12879 return null; 12880 } 12881 12882 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 12883 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 12884 userId, andCode ? 1 : 0, packageName); 12885 if (mSystemReady) { 12886 msg.sendToTarget(); 12887 } else { 12888 if (mPostSystemReadyMessages == null) { 12889 mPostSystemReadyMessages = new ArrayList<>(); 12890 } 12891 mPostSystemReadyMessages.add(msg); 12892 } 12893 } 12894 12895 void startCleaningPackages() { 12896 // reader 12897 if (!isExternalMediaAvailable()) { 12898 return; 12899 } 12900 synchronized (mPackages) { 12901 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 12902 return; 12903 } 12904 } 12905 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 12906 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 12907 IActivityManager am = ActivityManager.getService(); 12908 if (am != null) { 12909 try { 12910 am.startService(null, intent, null, -1, null, mContext.getOpPackageName(), 12911 UserHandle.USER_SYSTEM); 12912 } catch (RemoteException e) { 12913 } 12914 } 12915 } 12916 12917 @Override 12918 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 12919 int installFlags, String installerPackageName, int userId) { 12920 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 12921 12922 final int callingUid = Binder.getCallingUid(); 12923 enforceCrossUserPermission(callingUid, userId, 12924 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 12925 12926 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 12927 try { 12928 if (observer != null) { 12929 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 12930 } 12931 } catch (RemoteException re) { 12932 } 12933 return; 12934 } 12935 12936 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 12937 installFlags |= PackageManager.INSTALL_FROM_ADB; 12938 12939 } else { 12940 // Caller holds INSTALL_PACKAGES permission, so we're less strict 12941 // about installerPackageName. 12942 12943 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 12944 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 12945 } 12946 12947 UserHandle user; 12948 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 12949 user = UserHandle.ALL; 12950 } else { 12951 user = new UserHandle(userId); 12952 } 12953 12954 // Only system components can circumvent runtime permissions when installing. 12955 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 12956 && mContext.checkCallingOrSelfPermission(Manifest.permission 12957 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 12958 throw new SecurityException("You need the " 12959 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 12960 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 12961 } 12962 12963 if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0 12964 || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 12965 throw new IllegalArgumentException( 12966 "New installs into ASEC containers no longer supported"); 12967 } 12968 12969 final File originFile = new File(originPath); 12970 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 12971 12972 final Message msg = mHandler.obtainMessage(INIT_COPY); 12973 final VerificationInfo verificationInfo = new VerificationInfo( 12974 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 12975 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 12976 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 12977 null /*packageAbiOverride*/, null /*grantedPermissions*/, 12978 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN); 12979 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 12980 msg.obj = params; 12981 12982 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 12983 System.identityHashCode(msg.obj)); 12984 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 12985 System.identityHashCode(msg.obj)); 12986 12987 mHandler.sendMessage(msg); 12988 } 12989 12990 12991 /** 12992 * Ensure that the install reason matches what we know about the package installer (e.g. whether 12993 * it is acting on behalf on an enterprise or the user). 12994 * 12995 * Note that the ordering of the conditionals in this method is important. The checks we perform 12996 * are as follows, in this order: 12997 * 12998 * 1) If the install is being performed by a system app, we can trust the app to have set the 12999 * install reason correctly. Thus, we pass through the install reason unchanged, no matter 13000 * what it is. 13001 * 2) If the install is being performed by a device or profile owner app, the install reason 13002 * should be enterprise policy. However, we cannot be sure that the device or profile owner 13003 * set the install reason correctly. If the app targets an older SDK version where install 13004 * reasons did not exist yet, or if the app author simply forgot, the install reason may be 13005 * unset or wrong. Thus, we force the install reason to be enterprise policy. 13006 * 3) In all other cases, the install is being performed by a regular app that is neither part 13007 * of the system nor a device or profile owner. We have no reason to believe that this app is 13008 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was 13009 * set to enterprise policy and if so, change it to unknown instead. 13010 */ 13011 private int fixUpInstallReason(String installerPackageName, int installerUid, 13012 int installReason) { 13013 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid) 13014 == PERMISSION_GRANTED) { 13015 // If the install is being performed by a system app, we trust that app to have set the 13016 // install reason correctly. 13017 return installReason; 13018 } 13019 13020 final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 13021 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 13022 if (dpm != null) { 13023 ComponentName owner = null; 13024 try { 13025 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */); 13026 if (owner == null) { 13027 owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid)); 13028 } 13029 } catch (RemoteException e) { 13030 } 13031 if (owner != null && owner.getPackageName().equals(installerPackageName)) { 13032 // If the install is being performed by a device or profile owner, the install 13033 // reason should be enterprise policy. 13034 return PackageManager.INSTALL_REASON_POLICY; 13035 } 13036 } 13037 13038 if (installReason == PackageManager.INSTALL_REASON_POLICY) { 13039 // If the install is being performed by a regular app (i.e. neither system app nor 13040 // device or profile owner), we have no reason to believe that the app is acting on 13041 // behalf of an enterprise. If the app set the install reason to enterprise policy, 13042 // change it to unknown instead. 13043 return PackageManager.INSTALL_REASON_UNKNOWN; 13044 } 13045 13046 // If the install is being performed by a regular app and the install reason was set to any 13047 // value but enterprise policy, leave the install reason unchanged. 13048 return installReason; 13049 } 13050 13051 void installStage(String packageName, File stagedDir, String stagedCid, 13052 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 13053 String installerPackageName, int installerUid, UserHandle user, 13054 Certificate[][] certificates) { 13055 if (DEBUG_EPHEMERAL) { 13056 if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { 13057 Slog.d(TAG, "Ephemeral install of " + packageName); 13058 } 13059 } 13060 final VerificationInfo verificationInfo = new VerificationInfo( 13061 sessionParams.originatingUri, sessionParams.referrerUri, 13062 sessionParams.originatingUid, installerUid); 13063 13064 final OriginInfo origin; 13065 if (stagedDir != null) { 13066 origin = OriginInfo.fromStagedFile(stagedDir); 13067 } else { 13068 origin = OriginInfo.fromStagedContainer(stagedCid); 13069 } 13070 13071 final Message msg = mHandler.obtainMessage(INIT_COPY); 13072 final int installReason = fixUpInstallReason(installerPackageName, installerUid, 13073 sessionParams.installReason); 13074 final InstallParams params = new InstallParams(origin, null, observer, 13075 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 13076 verificationInfo, user, sessionParams.abiOverride, 13077 sessionParams.grantedRuntimePermissions, certificates, installReason); 13078 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 13079 msg.obj = params; 13080 13081 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 13082 System.identityHashCode(msg.obj)); 13083 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 13084 System.identityHashCode(msg.obj)); 13085 13086 mHandler.sendMessage(msg); 13087 } 13088 13089 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 13090 int userId) { 13091 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 13092 sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId); 13093 } 13094 13095 private void sendPackageAddedForNewUsers(String packageName, boolean isSystem, 13096 int appId, int... userIds) { 13097 if (ArrayUtils.isEmpty(userIds)) { 13098 return; 13099 } 13100 Bundle extras = new Bundle(1); 13101 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast 13102 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId)); 13103 13104 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 13105 packageName, extras, 0, null, null, userIds); 13106 if (isSystem) { 13107 mHandler.post(() -> { 13108 for (int userId : userIds) { 13109 sendBootCompletedBroadcastToSystemApp(packageName, userId); 13110 } 13111 } 13112 ); 13113 } 13114 } 13115 13116 /** 13117 * The just-installed/enabled app is bundled on the system, so presumed to be able to run 13118 * automatically without needing an explicit launch. 13119 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones. 13120 */ 13121 private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) { 13122 // If user is not running, the app didn't miss any broadcast 13123 if (!mUserManagerInternal.isUserRunning(userId)) { 13124 return; 13125 } 13126 final IActivityManager am = ActivityManager.getService(); 13127 try { 13128 // Deliver LOCKED_BOOT_COMPLETED first 13129 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED) 13130 .setPackage(packageName); 13131 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED}; 13132 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions, 13133 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 13134 13135 // Deliver BOOT_COMPLETED only if user is unlocked 13136 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) { 13137 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName); 13138 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions, 13139 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 13140 } 13141 } catch (RemoteException e) { 13142 throw e.rethrowFromSystemServer(); 13143 } 13144 } 13145 13146 @Override 13147 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 13148 int userId) { 13149 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13150 PackageSetting pkgSetting; 13151 final int uid = Binder.getCallingUid(); 13152 enforceCrossUserPermission(uid, userId, 13153 true /* requireFullPermission */, true /* checkShell */, 13154 "setApplicationHiddenSetting for user " + userId); 13155 13156 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 13157 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 13158 return false; 13159 } 13160 13161 long callingId = Binder.clearCallingIdentity(); 13162 try { 13163 boolean sendAdded = false; 13164 boolean sendRemoved = false; 13165 // writer 13166 synchronized (mPackages) { 13167 pkgSetting = mSettings.mPackages.get(packageName); 13168 if (pkgSetting == null) { 13169 return false; 13170 } 13171 // Do not allow "android" is being disabled 13172 if ("android".equals(packageName)) { 13173 Slog.w(TAG, "Cannot hide package: android"); 13174 return false; 13175 } 13176 // Cannot hide static shared libs as they are considered 13177 // a part of the using app (emulating static linking). Also 13178 // static libs are installed always on internal storage. 13179 PackageParser.Package pkg = mPackages.get(packageName); 13180 if (pkg != null && pkg.staticSharedLibName != null) { 13181 Slog.w(TAG, "Cannot hide package: " + packageName 13182 + " providing static shared library: " 13183 + pkg.staticSharedLibName); 13184 return false; 13185 } 13186 // Only allow protected packages to hide themselves. 13187 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 13188 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 13189 Slog.w(TAG, "Not hiding protected package: " + packageName); 13190 return false; 13191 } 13192 13193 if (pkgSetting.getHidden(userId) != hidden) { 13194 pkgSetting.setHidden(hidden, userId); 13195 mSettings.writePackageRestrictionsLPr(userId); 13196 if (hidden) { 13197 sendRemoved = true; 13198 } else { 13199 sendAdded = true; 13200 } 13201 } 13202 } 13203 if (sendAdded) { 13204 sendPackageAddedForUser(packageName, pkgSetting, userId); 13205 return true; 13206 } 13207 if (sendRemoved) { 13208 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 13209 "hiding pkg"); 13210 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 13211 return true; 13212 } 13213 } finally { 13214 Binder.restoreCallingIdentity(callingId); 13215 } 13216 return false; 13217 } 13218 13219 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 13220 int userId) { 13221 final PackageRemovedInfo info = new PackageRemovedInfo(); 13222 info.removedPackage = packageName; 13223 info.removedUsers = new int[] {userId}; 13224 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 13225 info.sendPackageRemovedBroadcasts(true /*killApp*/); 13226 } 13227 13228 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 13229 if (pkgList.length > 0) { 13230 Bundle extras = new Bundle(1); 13231 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 13232 13233 sendPackageBroadcast( 13234 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 13235 : Intent.ACTION_PACKAGES_UNSUSPENDED, 13236 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 13237 new int[] {userId}); 13238 } 13239 } 13240 13241 /** 13242 * Returns true if application is not found or there was an error. Otherwise it returns 13243 * the hidden state of the package for the given user. 13244 */ 13245 @Override 13246 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 13247 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13248 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13249 true /* requireFullPermission */, false /* checkShell */, 13250 "getApplicationHidden for user " + userId); 13251 PackageSetting pkgSetting; 13252 long callingId = Binder.clearCallingIdentity(); 13253 try { 13254 // writer 13255 synchronized (mPackages) { 13256 pkgSetting = mSettings.mPackages.get(packageName); 13257 if (pkgSetting == null) { 13258 return true; 13259 } 13260 return pkgSetting.getHidden(userId); 13261 } 13262 } finally { 13263 Binder.restoreCallingIdentity(callingId); 13264 } 13265 } 13266 13267 /** 13268 * @hide 13269 */ 13270 @Override 13271 public int installExistingPackageAsUser(String packageName, int userId, int installFlags, 13272 int installReason) { 13273 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 13274 null); 13275 PackageSetting pkgSetting; 13276 final int uid = Binder.getCallingUid(); 13277 enforceCrossUserPermission(uid, userId, 13278 true /* requireFullPermission */, true /* checkShell */, 13279 "installExistingPackage for user " + userId); 13280 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 13281 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 13282 } 13283 13284 long callingId = Binder.clearCallingIdentity(); 13285 try { 13286 boolean installed = false; 13287 final boolean instantApp = 13288 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 13289 final boolean fullApp = 13290 (installFlags & PackageManager.INSTALL_FULL_APP) != 0; 13291 13292 // writer 13293 synchronized (mPackages) { 13294 pkgSetting = mSettings.mPackages.get(packageName); 13295 if (pkgSetting == null) { 13296 return PackageManager.INSTALL_FAILED_INVALID_URI; 13297 } 13298 if (!pkgSetting.getInstalled(userId)) { 13299 pkgSetting.setInstalled(true, userId); 13300 pkgSetting.setHidden(false, userId); 13301 pkgSetting.setInstallReason(installReason, userId); 13302 mSettings.writePackageRestrictionsLPr(userId); 13303 mSettings.writeKernelMappingLPr(pkgSetting); 13304 installed = true; 13305 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 13306 // upgrade app from instant to full; we don't allow app downgrade 13307 installed = true; 13308 } 13309 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp); 13310 } 13311 13312 if (installed) { 13313 if (pkgSetting.pkg != null) { 13314 synchronized (mInstallLock) { 13315 // We don't need to freeze for a brand new install 13316 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 13317 } 13318 } 13319 sendPackageAddedForUser(packageName, pkgSetting, userId); 13320 synchronized (mPackages) { 13321 updateSequenceNumberLP(packageName, new int[]{ userId }); 13322 } 13323 } 13324 } finally { 13325 Binder.restoreCallingIdentity(callingId); 13326 } 13327 13328 return PackageManager.INSTALL_SUCCEEDED; 13329 } 13330 13331 void setInstantAppForUser(PackageSetting pkgSetting, int userId, 13332 boolean instantApp, boolean fullApp) { 13333 // no state specified; do nothing 13334 if (!instantApp && !fullApp) { 13335 return; 13336 } 13337 if (userId != UserHandle.USER_ALL) { 13338 if (instantApp && !pkgSetting.getInstantApp(userId)) { 13339 pkgSetting.setInstantApp(true /*instantApp*/, userId); 13340 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 13341 pkgSetting.setInstantApp(false /*instantApp*/, userId); 13342 } 13343 } else { 13344 for (int currentUserId : sUserManager.getUserIds()) { 13345 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) { 13346 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId); 13347 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) { 13348 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId); 13349 } 13350 } 13351 } 13352 } 13353 13354 boolean isUserRestricted(int userId, String restrictionKey) { 13355 Bundle restrictions = sUserManager.getUserRestrictions(userId); 13356 if (restrictions.getBoolean(restrictionKey, false)) { 13357 Log.w(TAG, "User is restricted: " + restrictionKey); 13358 return true; 13359 } 13360 return false; 13361 } 13362 13363 @Override 13364 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 13365 int userId) { 13366 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13367 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13368 true /* requireFullPermission */, true /* checkShell */, 13369 "setPackagesSuspended for user " + userId); 13370 13371 if (ArrayUtils.isEmpty(packageNames)) { 13372 return packageNames; 13373 } 13374 13375 // List of package names for whom the suspended state has changed. 13376 List<String> changedPackages = new ArrayList<>(packageNames.length); 13377 // List of package names for whom the suspended state is not set as requested in this 13378 // method. 13379 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 13380 long callingId = Binder.clearCallingIdentity(); 13381 try { 13382 for (int i = 0; i < packageNames.length; i++) { 13383 String packageName = packageNames[i]; 13384 boolean changed = false; 13385 final int appId; 13386 synchronized (mPackages) { 13387 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 13388 if (pkgSetting == null) { 13389 Slog.w(TAG, "Could not find package setting for package \"" + packageName 13390 + "\". Skipping suspending/un-suspending."); 13391 unactionedPackages.add(packageName); 13392 continue; 13393 } 13394 appId = pkgSetting.appId; 13395 if (pkgSetting.getSuspended(userId) != suspended) { 13396 if (!canSuspendPackageForUserLocked(packageName, userId)) { 13397 unactionedPackages.add(packageName); 13398 continue; 13399 } 13400 pkgSetting.setSuspended(suspended, userId); 13401 mSettings.writePackageRestrictionsLPr(userId); 13402 changed = true; 13403 changedPackages.add(packageName); 13404 } 13405 } 13406 13407 if (changed && suspended) { 13408 killApplication(packageName, UserHandle.getUid(userId, appId), 13409 "suspending package"); 13410 } 13411 } 13412 } finally { 13413 Binder.restoreCallingIdentity(callingId); 13414 } 13415 13416 if (!changedPackages.isEmpty()) { 13417 sendPackagesSuspendedForUser(changedPackages.toArray( 13418 new String[changedPackages.size()]), userId, suspended); 13419 } 13420 13421 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 13422 } 13423 13424 @Override 13425 public boolean isPackageSuspendedForUser(String packageName, int userId) { 13426 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13427 true /* requireFullPermission */, false /* checkShell */, 13428 "isPackageSuspendedForUser for user " + userId); 13429 synchronized (mPackages) { 13430 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 13431 if (pkgSetting == null) { 13432 throw new IllegalArgumentException("Unknown target package: " + packageName); 13433 } 13434 return pkgSetting.getSuspended(userId); 13435 } 13436 } 13437 13438 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 13439 if (isPackageDeviceAdmin(packageName, userId)) { 13440 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13441 + "\": has an active device admin"); 13442 return false; 13443 } 13444 13445 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 13446 if (packageName.equals(activeLauncherPackageName)) { 13447 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13448 + "\": contains the active launcher"); 13449 return false; 13450 } 13451 13452 if (packageName.equals(mRequiredInstallerPackage)) { 13453 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13454 + "\": required for package installation"); 13455 return false; 13456 } 13457 13458 if (packageName.equals(mRequiredUninstallerPackage)) { 13459 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13460 + "\": required for package uninstallation"); 13461 return false; 13462 } 13463 13464 if (packageName.equals(mRequiredVerifierPackage)) { 13465 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13466 + "\": required for package verification"); 13467 return false; 13468 } 13469 13470 if (packageName.equals(getDefaultDialerPackageName(userId))) { 13471 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13472 + "\": is the default dialer"); 13473 return false; 13474 } 13475 13476 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 13477 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13478 + "\": protected package"); 13479 return false; 13480 } 13481 13482 // Cannot suspend static shared libs as they are considered 13483 // a part of the using app (emulating static linking). Also 13484 // static libs are installed always on internal storage. 13485 PackageParser.Package pkg = mPackages.get(packageName); 13486 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) { 13487 Slog.w(TAG, "Cannot suspend package: " + packageName 13488 + " providing static shared library: " 13489 + pkg.staticSharedLibName); 13490 return false; 13491 } 13492 13493 return true; 13494 } 13495 13496 private String getActiveLauncherPackageName(int userId) { 13497 Intent intent = new Intent(Intent.ACTION_MAIN); 13498 intent.addCategory(Intent.CATEGORY_HOME); 13499 ResolveInfo resolveInfo = resolveIntent( 13500 intent, 13501 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 13502 PackageManager.MATCH_DEFAULT_ONLY, 13503 userId); 13504 13505 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 13506 } 13507 13508 private String getDefaultDialerPackageName(int userId) { 13509 synchronized (mPackages) { 13510 return mSettings.getDefaultDialerPackageNameLPw(userId); 13511 } 13512 } 13513 13514 @Override 13515 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 13516 mContext.enforceCallingOrSelfPermission( 13517 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13518 "Only package verification agents can verify applications"); 13519 13520 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 13521 final PackageVerificationResponse response = new PackageVerificationResponse( 13522 verificationCode, Binder.getCallingUid()); 13523 msg.arg1 = id; 13524 msg.obj = response; 13525 mHandler.sendMessage(msg); 13526 } 13527 13528 @Override 13529 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 13530 long millisecondsToDelay) { 13531 mContext.enforceCallingOrSelfPermission( 13532 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13533 "Only package verification agents can extend verification timeouts"); 13534 13535 final PackageVerificationState state = mPendingVerification.get(id); 13536 final PackageVerificationResponse response = new PackageVerificationResponse( 13537 verificationCodeAtTimeout, Binder.getCallingUid()); 13538 13539 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 13540 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 13541 } 13542 if (millisecondsToDelay < 0) { 13543 millisecondsToDelay = 0; 13544 } 13545 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 13546 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 13547 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 13548 } 13549 13550 if ((state != null) && !state.timeoutExtended()) { 13551 state.extendTimeout(); 13552 13553 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 13554 msg.arg1 = id; 13555 msg.obj = response; 13556 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 13557 } 13558 } 13559 13560 private void broadcastPackageVerified(int verificationId, Uri packageUri, 13561 int verificationCode, UserHandle user) { 13562 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 13563 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 13564 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 13565 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 13566 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 13567 13568 mContext.sendBroadcastAsUser(intent, user, 13569 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 13570 } 13571 13572 private ComponentName matchComponentForVerifier(String packageName, 13573 List<ResolveInfo> receivers) { 13574 ActivityInfo targetReceiver = null; 13575 13576 final int NR = receivers.size(); 13577 for (int i = 0; i < NR; i++) { 13578 final ResolveInfo info = receivers.get(i); 13579 if (info.activityInfo == null) { 13580 continue; 13581 } 13582 13583 if (packageName.equals(info.activityInfo.packageName)) { 13584 targetReceiver = info.activityInfo; 13585 break; 13586 } 13587 } 13588 13589 if (targetReceiver == null) { 13590 return null; 13591 } 13592 13593 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 13594 } 13595 13596 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 13597 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 13598 if (pkgInfo.verifiers.length == 0) { 13599 return null; 13600 } 13601 13602 final int N = pkgInfo.verifiers.length; 13603 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 13604 for (int i = 0; i < N; i++) { 13605 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 13606 13607 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 13608 receivers); 13609 if (comp == null) { 13610 continue; 13611 } 13612 13613 final int verifierUid = getUidForVerifier(verifierInfo); 13614 if (verifierUid == -1) { 13615 continue; 13616 } 13617 13618 if (DEBUG_VERIFY) { 13619 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 13620 + " with the correct signature"); 13621 } 13622 sufficientVerifiers.add(comp); 13623 verificationState.addSufficientVerifier(verifierUid); 13624 } 13625 13626 return sufficientVerifiers; 13627 } 13628 13629 private int getUidForVerifier(VerifierInfo verifierInfo) { 13630 synchronized (mPackages) { 13631 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 13632 if (pkg == null) { 13633 return -1; 13634 } else if (pkg.mSignatures.length != 1) { 13635 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 13636 + " has more than one signature; ignoring"); 13637 return -1; 13638 } 13639 13640 /* 13641 * If the public key of the package's signature does not match 13642 * our expected public key, then this is a different package and 13643 * we should skip. 13644 */ 13645 13646 final byte[] expectedPublicKey; 13647 try { 13648 final Signature verifierSig = pkg.mSignatures[0]; 13649 final PublicKey publicKey = verifierSig.getPublicKey(); 13650 expectedPublicKey = publicKey.getEncoded(); 13651 } catch (CertificateException e) { 13652 return -1; 13653 } 13654 13655 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 13656 13657 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 13658 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 13659 + " does not have the expected public key; ignoring"); 13660 return -1; 13661 } 13662 13663 return pkg.applicationInfo.uid; 13664 } 13665 } 13666 13667 @Override 13668 public void finishPackageInstall(int token, boolean didLaunch) { 13669 enforceSystemOrRoot("Only the system is allowed to finish installs"); 13670 13671 if (DEBUG_INSTALL) { 13672 Slog.v(TAG, "BM finishing package install for " + token); 13673 } 13674 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 13675 13676 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 13677 mHandler.sendMessage(msg); 13678 } 13679 13680 /** 13681 * Get the verification agent timeout. 13682 * 13683 * @return verification timeout in milliseconds 13684 */ 13685 private long getVerificationTimeout() { 13686 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 13687 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 13688 DEFAULT_VERIFICATION_TIMEOUT); 13689 } 13690 13691 /** 13692 * Get the default verification agent response code. 13693 * 13694 * @return default verification response code 13695 */ 13696 private int getDefaultVerificationResponse() { 13697 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13698 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 13699 DEFAULT_VERIFICATION_RESPONSE); 13700 } 13701 13702 /** 13703 * Check whether or not package verification has been enabled. 13704 * 13705 * @return true if verification should be performed 13706 */ 13707 private boolean isVerificationEnabled(int userId, int installFlags) { 13708 if (!DEFAULT_VERIFY_ENABLE) { 13709 return false; 13710 } 13711 13712 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 13713 13714 // Check if installing from ADB 13715 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 13716 // Do not run verification in a test harness environment 13717 if (ActivityManager.isRunningInTestHarness()) { 13718 return false; 13719 } 13720 if (ensureVerifyAppsEnabled) { 13721 return true; 13722 } 13723 // Check if the developer does not want package verification for ADB installs 13724 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13725 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 13726 return false; 13727 } 13728 } 13729 13730 if (ensureVerifyAppsEnabled) { 13731 return true; 13732 } 13733 13734 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13735 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 13736 } 13737 13738 @Override 13739 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 13740 throws RemoteException { 13741 mContext.enforceCallingOrSelfPermission( 13742 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 13743 "Only intentfilter verification agents can verify applications"); 13744 13745 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 13746 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 13747 Binder.getCallingUid(), verificationCode, failedDomains); 13748 msg.arg1 = id; 13749 msg.obj = response; 13750 mHandler.sendMessage(msg); 13751 } 13752 13753 @Override 13754 public int getIntentVerificationStatus(String packageName, int userId) { 13755 synchronized (mPackages) { 13756 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 13757 } 13758 } 13759 13760 @Override 13761 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 13762 mContext.enforceCallingOrSelfPermission( 13763 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13764 13765 boolean result = false; 13766 synchronized (mPackages) { 13767 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 13768 } 13769 if (result) { 13770 scheduleWritePackageRestrictionsLocked(userId); 13771 } 13772 return result; 13773 } 13774 13775 @Override 13776 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 13777 String packageName) { 13778 synchronized (mPackages) { 13779 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 13780 } 13781 } 13782 13783 @Override 13784 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 13785 if (TextUtils.isEmpty(packageName)) { 13786 return ParceledListSlice.emptyList(); 13787 } 13788 synchronized (mPackages) { 13789 PackageParser.Package pkg = mPackages.get(packageName); 13790 if (pkg == null || pkg.activities == null) { 13791 return ParceledListSlice.emptyList(); 13792 } 13793 final int count = pkg.activities.size(); 13794 ArrayList<IntentFilter> result = new ArrayList<>(); 13795 for (int n=0; n<count; n++) { 13796 PackageParser.Activity activity = pkg.activities.get(n); 13797 if (activity.intents != null && activity.intents.size() > 0) { 13798 result.addAll(activity.intents); 13799 } 13800 } 13801 return new ParceledListSlice<>(result); 13802 } 13803 } 13804 13805 @Override 13806 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 13807 mContext.enforceCallingOrSelfPermission( 13808 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13809 13810 synchronized (mPackages) { 13811 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 13812 if (packageName != null) { 13813 result |= updateIntentVerificationStatus(packageName, 13814 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 13815 userId); 13816 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 13817 packageName, userId); 13818 } 13819 return result; 13820 } 13821 } 13822 13823 @Override 13824 public String getDefaultBrowserPackageName(int userId) { 13825 synchronized (mPackages) { 13826 return mSettings.getDefaultBrowserPackageNameLPw(userId); 13827 } 13828 } 13829 13830 /** 13831 * Get the "allow unknown sources" setting. 13832 * 13833 * @return the current "allow unknown sources" setting 13834 */ 13835 private int getUnknownSourcesSettings() { 13836 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 13837 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 13838 -1); 13839 } 13840 13841 @Override 13842 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 13843 final int uid = Binder.getCallingUid(); 13844 // writer 13845 synchronized (mPackages) { 13846 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 13847 if (targetPackageSetting == null) { 13848 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 13849 } 13850 13851 PackageSetting installerPackageSetting; 13852 if (installerPackageName != null) { 13853 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 13854 if (installerPackageSetting == null) { 13855 throw new IllegalArgumentException("Unknown installer package: " 13856 + installerPackageName); 13857 } 13858 } else { 13859 installerPackageSetting = null; 13860 } 13861 13862 Signature[] callerSignature; 13863 Object obj = mSettings.getUserIdLPr(uid); 13864 if (obj != null) { 13865 if (obj instanceof SharedUserSetting) { 13866 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 13867 } else if (obj instanceof PackageSetting) { 13868 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 13869 } else { 13870 throw new SecurityException("Bad object " + obj + " for uid " + uid); 13871 } 13872 } else { 13873 throw new SecurityException("Unknown calling UID: " + uid); 13874 } 13875 13876 // Verify: can't set installerPackageName to a package that is 13877 // not signed with the same cert as the caller. 13878 if (installerPackageSetting != null) { 13879 if (compareSignatures(callerSignature, 13880 installerPackageSetting.signatures.mSignatures) 13881 != PackageManager.SIGNATURE_MATCH) { 13882 throw new SecurityException( 13883 "Caller does not have same cert as new installer package " 13884 + installerPackageName); 13885 } 13886 } 13887 13888 // Verify: if target already has an installer package, it must 13889 // be signed with the same cert as the caller. 13890 if (targetPackageSetting.installerPackageName != null) { 13891 PackageSetting setting = mSettings.mPackages.get( 13892 targetPackageSetting.installerPackageName); 13893 // If the currently set package isn't valid, then it's always 13894 // okay to change it. 13895 if (setting != null) { 13896 if (compareSignatures(callerSignature, 13897 setting.signatures.mSignatures) 13898 != PackageManager.SIGNATURE_MATCH) { 13899 throw new SecurityException( 13900 "Caller does not have same cert as old installer package " 13901 + targetPackageSetting.installerPackageName); 13902 } 13903 } 13904 } 13905 13906 // Okay! 13907 targetPackageSetting.installerPackageName = installerPackageName; 13908 if (installerPackageName != null) { 13909 mSettings.mInstallerPackages.add(installerPackageName); 13910 } 13911 scheduleWriteSettingsLocked(); 13912 } 13913 } 13914 13915 @Override 13916 public void setApplicationCategoryHint(String packageName, int categoryHint, 13917 String callerPackageName) { 13918 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), 13919 callerPackageName); 13920 synchronized (mPackages) { 13921 PackageSetting ps = mSettings.mPackages.get(packageName); 13922 if (ps == null) { 13923 throw new IllegalArgumentException("Unknown target package " + packageName); 13924 } 13925 13926 if (!Objects.equals(callerPackageName, ps.installerPackageName)) { 13927 throw new IllegalArgumentException("Calling package " + callerPackageName 13928 + " is not installer for " + packageName); 13929 } 13930 13931 if (ps.categoryHint != categoryHint) { 13932 ps.categoryHint = categoryHint; 13933 scheduleWriteSettingsLocked(); 13934 } 13935 } 13936 } 13937 13938 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 13939 // Queue up an async operation since the package installation may take a little while. 13940 mHandler.post(new Runnable() { 13941 public void run() { 13942 mHandler.removeCallbacks(this); 13943 // Result object to be returned 13944 PackageInstalledInfo res = new PackageInstalledInfo(); 13945 res.setReturnCode(currentStatus); 13946 res.uid = -1; 13947 res.pkg = null; 13948 res.removedInfo = null; 13949 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13950 args.doPreInstall(res.returnCode); 13951 synchronized (mInstallLock) { 13952 installPackageTracedLI(args, res); 13953 } 13954 args.doPostInstall(res.returnCode, res.uid); 13955 } 13956 13957 // A restore should be performed at this point if (a) the install 13958 // succeeded, (b) the operation is not an update, and (c) the new 13959 // package has not opted out of backup participation. 13960 final boolean update = res.removedInfo != null 13961 && res.removedInfo.removedPackage != null; 13962 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 13963 boolean doRestore = !update 13964 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 13965 13966 // Set up the post-install work request bookkeeping. This will be used 13967 // and cleaned up by the post-install event handling regardless of whether 13968 // there's a restore pass performed. Token values are >= 1. 13969 int token; 13970 if (mNextInstallToken < 0) mNextInstallToken = 1; 13971 token = mNextInstallToken++; 13972 13973 PostInstallData data = new PostInstallData(args, res); 13974 mRunningInstalls.put(token, data); 13975 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 13976 13977 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 13978 // Pass responsibility to the Backup Manager. It will perform a 13979 // restore if appropriate, then pass responsibility back to the 13980 // Package Manager to run the post-install observer callbacks 13981 // and broadcasts. 13982 IBackupManager bm = IBackupManager.Stub.asInterface( 13983 ServiceManager.getService(Context.BACKUP_SERVICE)); 13984 if (bm != null) { 13985 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 13986 + " to BM for possible restore"); 13987 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 13988 try { 13989 // TODO: http://b/22388012 13990 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 13991 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 13992 } else { 13993 doRestore = false; 13994 } 13995 } catch (RemoteException e) { 13996 // can't happen; the backup manager is local 13997 } catch (Exception e) { 13998 Slog.e(TAG, "Exception trying to enqueue restore", e); 13999 doRestore = false; 14000 } 14001 } else { 14002 Slog.e(TAG, "Backup Manager not found!"); 14003 doRestore = false; 14004 } 14005 } 14006 14007 if (!doRestore) { 14008 // No restore possible, or the Backup Manager was mysteriously not 14009 // available -- just fire the post-install work request directly. 14010 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 14011 14012 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 14013 14014 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 14015 mHandler.sendMessage(msg); 14016 } 14017 } 14018 }); 14019 } 14020 14021 /** 14022 * Callback from PackageSettings whenever an app is first transitioned out of the 14023 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 14024 * the app was "launched" for a restoreAtInstall operation. Therefore we check 14025 * here whether the app is the target of an ongoing install, and only send the 14026 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 14027 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 14028 * handling. 14029 */ 14030 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 14031 // Serialize this with the rest of the install-process message chain. In the 14032 // restore-at-install case, this Runnable will necessarily run before the 14033 // POST_INSTALL message is processed, so the contents of mRunningInstalls 14034 // are coherent. In the non-restore case, the app has already completed install 14035 // and been launched through some other means, so it is not in a problematic 14036 // state for observers to see the FIRST_LAUNCH signal. 14037 mHandler.post(new Runnable() { 14038 @Override 14039 public void run() { 14040 for (int i = 0; i < mRunningInstalls.size(); i++) { 14041 final PostInstallData data = mRunningInstalls.valueAt(i); 14042 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14043 continue; 14044 } 14045 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 14046 // right package; but is it for the right user? 14047 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 14048 if (userId == data.res.newUsers[uIndex]) { 14049 if (DEBUG_BACKUP) { 14050 Slog.i(TAG, "Package " + pkgName 14051 + " being restored so deferring FIRST_LAUNCH"); 14052 } 14053 return; 14054 } 14055 } 14056 } 14057 } 14058 // didn't find it, so not being restored 14059 if (DEBUG_BACKUP) { 14060 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 14061 } 14062 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 14063 } 14064 }); 14065 } 14066 14067 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 14068 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 14069 installerPkg, null, userIds); 14070 } 14071 14072 private abstract class HandlerParams { 14073 private static final int MAX_RETRIES = 4; 14074 14075 /** 14076 * Number of times startCopy() has been attempted and had a non-fatal 14077 * error. 14078 */ 14079 private int mRetries = 0; 14080 14081 /** User handle for the user requesting the information or installation. */ 14082 private final UserHandle mUser; 14083 String traceMethod; 14084 int traceCookie; 14085 14086 HandlerParams(UserHandle user) { 14087 mUser = user; 14088 } 14089 14090 UserHandle getUser() { 14091 return mUser; 14092 } 14093 14094 HandlerParams setTraceMethod(String traceMethod) { 14095 this.traceMethod = traceMethod; 14096 return this; 14097 } 14098 14099 HandlerParams setTraceCookie(int traceCookie) { 14100 this.traceCookie = traceCookie; 14101 return this; 14102 } 14103 14104 final boolean startCopy() { 14105 boolean res; 14106 try { 14107 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 14108 14109 if (++mRetries > MAX_RETRIES) { 14110 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 14111 mHandler.sendEmptyMessage(MCS_GIVE_UP); 14112 handleServiceError(); 14113 return false; 14114 } else { 14115 handleStartCopy(); 14116 res = true; 14117 } 14118 } catch (RemoteException e) { 14119 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 14120 mHandler.sendEmptyMessage(MCS_RECONNECT); 14121 res = false; 14122 } 14123 handleReturnCode(); 14124 return res; 14125 } 14126 14127 final void serviceError() { 14128 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 14129 handleServiceError(); 14130 handleReturnCode(); 14131 } 14132 14133 abstract void handleStartCopy() throws RemoteException; 14134 abstract void handleServiceError(); 14135 abstract void handleReturnCode(); 14136 } 14137 14138 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 14139 for (File path : paths) { 14140 try { 14141 mcs.clearDirectory(path.getAbsolutePath()); 14142 } catch (RemoteException e) { 14143 } 14144 } 14145 } 14146 14147 static class OriginInfo { 14148 /** 14149 * Location where install is coming from, before it has been 14150 * copied/renamed into place. This could be a single monolithic APK 14151 * file, or a cluster directory. This location may be untrusted. 14152 */ 14153 final File file; 14154 final String cid; 14155 14156 /** 14157 * Flag indicating that {@link #file} or {@link #cid} has already been 14158 * staged, meaning downstream users don't need to defensively copy the 14159 * contents. 14160 */ 14161 final boolean staged; 14162 14163 /** 14164 * Flag indicating that {@link #file} or {@link #cid} is an already 14165 * installed app that is being moved. 14166 */ 14167 final boolean existing; 14168 14169 final String resolvedPath; 14170 final File resolvedFile; 14171 14172 static OriginInfo fromNothing() { 14173 return new OriginInfo(null, null, false, false); 14174 } 14175 14176 static OriginInfo fromUntrustedFile(File file) { 14177 return new OriginInfo(file, null, false, false); 14178 } 14179 14180 static OriginInfo fromExistingFile(File file) { 14181 return new OriginInfo(file, null, false, true); 14182 } 14183 14184 static OriginInfo fromStagedFile(File file) { 14185 return new OriginInfo(file, null, true, false); 14186 } 14187 14188 static OriginInfo fromStagedContainer(String cid) { 14189 return new OriginInfo(null, cid, true, false); 14190 } 14191 14192 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 14193 this.file = file; 14194 this.cid = cid; 14195 this.staged = staged; 14196 this.existing = existing; 14197 14198 if (cid != null) { 14199 resolvedPath = PackageHelper.getSdDir(cid); 14200 resolvedFile = new File(resolvedPath); 14201 } else if (file != null) { 14202 resolvedPath = file.getAbsolutePath(); 14203 resolvedFile = file; 14204 } else { 14205 resolvedPath = null; 14206 resolvedFile = null; 14207 } 14208 } 14209 } 14210 14211 static class MoveInfo { 14212 final int moveId; 14213 final String fromUuid; 14214 final String toUuid; 14215 final String packageName; 14216 final String dataAppName; 14217 final int appId; 14218 final String seinfo; 14219 final int targetSdkVersion; 14220 14221 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 14222 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 14223 this.moveId = moveId; 14224 this.fromUuid = fromUuid; 14225 this.toUuid = toUuid; 14226 this.packageName = packageName; 14227 this.dataAppName = dataAppName; 14228 this.appId = appId; 14229 this.seinfo = seinfo; 14230 this.targetSdkVersion = targetSdkVersion; 14231 } 14232 } 14233 14234 static class VerificationInfo { 14235 /** A constant used to indicate that a uid value is not present. */ 14236 public static final int NO_UID = -1; 14237 14238 /** URI referencing where the package was downloaded from. */ 14239 final Uri originatingUri; 14240 14241 /** HTTP referrer URI associated with the originatingURI. */ 14242 final Uri referrer; 14243 14244 /** UID of the application that the install request originated from. */ 14245 final int originatingUid; 14246 14247 /** UID of application requesting the install */ 14248 final int installerUid; 14249 14250 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 14251 this.originatingUri = originatingUri; 14252 this.referrer = referrer; 14253 this.originatingUid = originatingUid; 14254 this.installerUid = installerUid; 14255 } 14256 } 14257 14258 class InstallParams extends HandlerParams { 14259 final OriginInfo origin; 14260 final MoveInfo move; 14261 final IPackageInstallObserver2 observer; 14262 int installFlags; 14263 final String installerPackageName; 14264 final String volumeUuid; 14265 private InstallArgs mArgs; 14266 private int mRet; 14267 final String packageAbiOverride; 14268 final String[] grantedRuntimePermissions; 14269 final VerificationInfo verificationInfo; 14270 final Certificate[][] certificates; 14271 final int installReason; 14272 14273 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 14274 int installFlags, String installerPackageName, String volumeUuid, 14275 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 14276 String[] grantedPermissions, Certificate[][] certificates, int installReason) { 14277 super(user); 14278 this.origin = origin; 14279 this.move = move; 14280 this.observer = observer; 14281 this.installFlags = installFlags; 14282 this.installerPackageName = installerPackageName; 14283 this.volumeUuid = volumeUuid; 14284 this.verificationInfo = verificationInfo; 14285 this.packageAbiOverride = packageAbiOverride; 14286 this.grantedRuntimePermissions = grantedPermissions; 14287 this.certificates = certificates; 14288 this.installReason = installReason; 14289 } 14290 14291 @Override 14292 public String toString() { 14293 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 14294 + " file=" + origin.file + " cid=" + origin.cid + "}"; 14295 } 14296 14297 private int installLocationPolicy(PackageInfoLite pkgLite) { 14298 String packageName = pkgLite.packageName; 14299 int installLocation = pkgLite.installLocation; 14300 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14301 // reader 14302 synchronized (mPackages) { 14303 // Currently installed package which the new package is attempting to replace or 14304 // null if no such package is installed. 14305 PackageParser.Package installedPkg = mPackages.get(packageName); 14306 // Package which currently owns the data which the new package will own if installed. 14307 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 14308 // will be null whereas dataOwnerPkg will contain information about the package 14309 // which was uninstalled while keeping its data. 14310 PackageParser.Package dataOwnerPkg = installedPkg; 14311 if (dataOwnerPkg == null) { 14312 PackageSetting ps = mSettings.mPackages.get(packageName); 14313 if (ps != null) { 14314 dataOwnerPkg = ps.pkg; 14315 } 14316 } 14317 14318 if (dataOwnerPkg != null) { 14319 // If installed, the package will get access to data left on the device by its 14320 // predecessor. As a security measure, this is permited only if this is not a 14321 // version downgrade or if the predecessor package is marked as debuggable and 14322 // a downgrade is explicitly requested. 14323 // 14324 // On debuggable platform builds, downgrades are permitted even for 14325 // non-debuggable packages to make testing easier. Debuggable platform builds do 14326 // not offer security guarantees and thus it's OK to disable some security 14327 // mechanisms to make debugging/testing easier on those builds. However, even on 14328 // debuggable builds downgrades of packages are permitted only if requested via 14329 // installFlags. This is because we aim to keep the behavior of debuggable 14330 // platform builds as close as possible to the behavior of non-debuggable 14331 // platform builds. 14332 final boolean downgradeRequested = 14333 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 14334 final boolean packageDebuggable = 14335 (dataOwnerPkg.applicationInfo.flags 14336 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 14337 final boolean downgradePermitted = 14338 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 14339 if (!downgradePermitted) { 14340 try { 14341 checkDowngrade(dataOwnerPkg, pkgLite); 14342 } catch (PackageManagerException e) { 14343 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 14344 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 14345 } 14346 } 14347 } 14348 14349 if (installedPkg != null) { 14350 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 14351 // Check for updated system application. 14352 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14353 if (onSd) { 14354 Slog.w(TAG, "Cannot install update to system app on sdcard"); 14355 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 14356 } 14357 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14358 } else { 14359 if (onSd) { 14360 // Install flag overrides everything. 14361 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14362 } 14363 // If current upgrade specifies particular preference 14364 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 14365 // Application explicitly specified internal. 14366 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14367 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 14368 // App explictly prefers external. Let policy decide 14369 } else { 14370 // Prefer previous location 14371 if (isExternal(installedPkg)) { 14372 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14373 } 14374 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14375 } 14376 } 14377 } else { 14378 // Invalid install. Return error code 14379 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 14380 } 14381 } 14382 } 14383 // All the special cases have been taken care of. 14384 // Return result based on recommended install location. 14385 if (onSd) { 14386 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14387 } 14388 return pkgLite.recommendedInstallLocation; 14389 } 14390 14391 /* 14392 * Invoke remote method to get package information and install 14393 * location values. Override install location based on default 14394 * policy if needed and then create install arguments based 14395 * on the install location. 14396 */ 14397 public void handleStartCopy() throws RemoteException { 14398 int ret = PackageManager.INSTALL_SUCCEEDED; 14399 14400 // If we're already staged, we've firmly committed to an install location 14401 if (origin.staged) { 14402 if (origin.file != null) { 14403 installFlags |= PackageManager.INSTALL_INTERNAL; 14404 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 14405 } else if (origin.cid != null) { 14406 installFlags |= PackageManager.INSTALL_EXTERNAL; 14407 installFlags &= ~PackageManager.INSTALL_INTERNAL; 14408 } else { 14409 throw new IllegalStateException("Invalid stage location"); 14410 } 14411 } 14412 14413 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14414 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 14415 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14416 PackageInfoLite pkgLite = null; 14417 14418 if (onInt && onSd) { 14419 // Check if both bits are set. 14420 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 14421 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14422 } else if (onSd && ephemeral) { 14423 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 14424 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14425 } else { 14426 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 14427 packageAbiOverride); 14428 14429 if (DEBUG_EPHEMERAL && ephemeral) { 14430 Slog.v(TAG, "pkgLite for install: " + pkgLite); 14431 } 14432 14433 /* 14434 * If we have too little free space, try to free cache 14435 * before giving up. 14436 */ 14437 if (!origin.staged && pkgLite.recommendedInstallLocation 14438 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 14439 // TODO: focus freeing disk space on the target device 14440 final StorageManager storage = StorageManager.from(mContext); 14441 final long lowThreshold = storage.getStorageLowBytes( 14442 Environment.getDataDirectory()); 14443 14444 final long sizeBytes = mContainerService.calculateInstalledSize( 14445 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 14446 14447 try { 14448 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0); 14449 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 14450 installFlags, packageAbiOverride); 14451 } catch (InstallerException e) { 14452 Slog.w(TAG, "Failed to free cache", e); 14453 } 14454 14455 /* 14456 * The cache free must have deleted the file we 14457 * downloaded to install. 14458 * 14459 * TODO: fix the "freeCache" call to not delete 14460 * the file we care about. 14461 */ 14462 if (pkgLite.recommendedInstallLocation 14463 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 14464 pkgLite.recommendedInstallLocation 14465 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 14466 } 14467 } 14468 } 14469 14470 if (ret == PackageManager.INSTALL_SUCCEEDED) { 14471 int loc = pkgLite.recommendedInstallLocation; 14472 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 14473 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14474 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 14475 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 14476 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 14477 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 14478 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 14479 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 14480 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 14481 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 14482 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 14483 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 14484 } else { 14485 // Override with defaults if needed. 14486 loc = installLocationPolicy(pkgLite); 14487 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 14488 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 14489 } else if (!onSd && !onInt) { 14490 // Override install location with flags 14491 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 14492 // Set the flag to install on external media. 14493 installFlags |= PackageManager.INSTALL_EXTERNAL; 14494 installFlags &= ~PackageManager.INSTALL_INTERNAL; 14495 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 14496 if (DEBUG_EPHEMERAL) { 14497 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 14498 } 14499 installFlags |= PackageManager.INSTALL_INSTANT_APP; 14500 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 14501 |PackageManager.INSTALL_INTERNAL); 14502 } else { 14503 // Make sure the flag for installing on external 14504 // media is unset 14505 installFlags |= PackageManager.INSTALL_INTERNAL; 14506 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 14507 } 14508 } 14509 } 14510 } 14511 14512 final InstallArgs args = createInstallArgs(this); 14513 mArgs = args; 14514 14515 if (ret == PackageManager.INSTALL_SUCCEEDED) { 14516 // TODO: http://b/22976637 14517 // Apps installed for "all" users use the device owner to verify the app 14518 UserHandle verifierUser = getUser(); 14519 if (verifierUser == UserHandle.ALL) { 14520 verifierUser = UserHandle.SYSTEM; 14521 } 14522 14523 /* 14524 * Determine if we have any installed package verifiers. If we 14525 * do, then we'll defer to them to verify the packages. 14526 */ 14527 final int requiredUid = mRequiredVerifierPackage == null ? -1 14528 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 14529 verifierUser.getIdentifier()); 14530 if (!origin.existing && requiredUid != -1 14531 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 14532 final Intent verification = new Intent( 14533 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 14534 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14535 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 14536 PACKAGE_MIME_TYPE); 14537 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 14538 14539 // Query all live verifiers based on current user state 14540 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 14541 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 14542 14543 if (DEBUG_VERIFY) { 14544 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 14545 + verification.toString() + " with " + pkgLite.verifiers.length 14546 + " optional verifiers"); 14547 } 14548 14549 final int verificationId = mPendingVerificationToken++; 14550 14551 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 14552 14553 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 14554 installerPackageName); 14555 14556 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 14557 installFlags); 14558 14559 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 14560 pkgLite.packageName); 14561 14562 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 14563 pkgLite.versionCode); 14564 14565 if (verificationInfo != null) { 14566 if (verificationInfo.originatingUri != null) { 14567 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 14568 verificationInfo.originatingUri); 14569 } 14570 if (verificationInfo.referrer != null) { 14571 verification.putExtra(Intent.EXTRA_REFERRER, 14572 verificationInfo.referrer); 14573 } 14574 if (verificationInfo.originatingUid >= 0) { 14575 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 14576 verificationInfo.originatingUid); 14577 } 14578 if (verificationInfo.installerUid >= 0) { 14579 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 14580 verificationInfo.installerUid); 14581 } 14582 } 14583 14584 final PackageVerificationState verificationState = new PackageVerificationState( 14585 requiredUid, args); 14586 14587 mPendingVerification.append(verificationId, verificationState); 14588 14589 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 14590 receivers, verificationState); 14591 14592 DeviceIdleController.LocalService idleController = getDeviceIdleController(); 14593 final long idleDuration = getVerificationTimeout(); 14594 14595 /* 14596 * If any sufficient verifiers were listed in the package 14597 * manifest, attempt to ask them. 14598 */ 14599 if (sufficientVerifiers != null) { 14600 final int N = sufficientVerifiers.size(); 14601 if (N == 0) { 14602 Slog.i(TAG, "Additional verifiers required, but none installed."); 14603 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 14604 } else { 14605 for (int i = 0; i < N; i++) { 14606 final ComponentName verifierComponent = sufficientVerifiers.get(i); 14607 idleController.addPowerSaveTempWhitelistApp(Process.myUid(), 14608 verifierComponent.getPackageName(), idleDuration, 14609 verifierUser.getIdentifier(), false, "package verifier"); 14610 14611 final Intent sufficientIntent = new Intent(verification); 14612 sufficientIntent.setComponent(verifierComponent); 14613 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 14614 } 14615 } 14616 } 14617 14618 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 14619 mRequiredVerifierPackage, receivers); 14620 if (ret == PackageManager.INSTALL_SUCCEEDED 14621 && mRequiredVerifierPackage != null) { 14622 Trace.asyncTraceBegin( 14623 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 14624 /* 14625 * Send the intent to the required verification agent, 14626 * but only start the verification timeout after the 14627 * target BroadcastReceivers have run. 14628 */ 14629 verification.setComponent(requiredVerifierComponent); 14630 idleController.addPowerSaveTempWhitelistApp(Process.myUid(), 14631 mRequiredVerifierPackage, idleDuration, 14632 verifierUser.getIdentifier(), false, "package verifier"); 14633 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 14634 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 14635 new BroadcastReceiver() { 14636 @Override 14637 public void onReceive(Context context, Intent intent) { 14638 final Message msg = mHandler 14639 .obtainMessage(CHECK_PENDING_VERIFICATION); 14640 msg.arg1 = verificationId; 14641 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 14642 } 14643 }, null, 0, null, null); 14644 14645 /* 14646 * We don't want the copy to proceed until verification 14647 * succeeds, so null out this field. 14648 */ 14649 mArgs = null; 14650 } 14651 } else { 14652 /* 14653 * No package verification is enabled, so immediately start 14654 * the remote call to initiate copy using temporary file. 14655 */ 14656 ret = args.copyApk(mContainerService, true); 14657 } 14658 } 14659 14660 mRet = ret; 14661 } 14662 14663 @Override 14664 void handleReturnCode() { 14665 // If mArgs is null, then MCS couldn't be reached. When it 14666 // reconnects, it will try again to install. At that point, this 14667 // will succeed. 14668 if (mArgs != null) { 14669 processPendingInstall(mArgs, mRet); 14670 } 14671 } 14672 14673 @Override 14674 void handleServiceError() { 14675 mArgs = createInstallArgs(this); 14676 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 14677 } 14678 14679 public boolean isForwardLocked() { 14680 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14681 } 14682 } 14683 14684 /** 14685 * Used during creation of InstallArgs 14686 * 14687 * @param installFlags package installation flags 14688 * @return true if should be installed on external storage 14689 */ 14690 private static boolean installOnExternalAsec(int installFlags) { 14691 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 14692 return false; 14693 } 14694 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 14695 return true; 14696 } 14697 return false; 14698 } 14699 14700 /** 14701 * Used during creation of InstallArgs 14702 * 14703 * @param installFlags package installation flags 14704 * @return true if should be installed as forward locked 14705 */ 14706 private static boolean installForwardLocked(int installFlags) { 14707 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14708 } 14709 14710 private InstallArgs createInstallArgs(InstallParams params) { 14711 if (params.move != null) { 14712 return new MoveInstallArgs(params); 14713 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 14714 return new AsecInstallArgs(params); 14715 } else { 14716 return new FileInstallArgs(params); 14717 } 14718 } 14719 14720 /** 14721 * Create args that describe an existing installed package. Typically used 14722 * when cleaning up old installs, or used as a move source. 14723 */ 14724 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 14725 String resourcePath, String[] instructionSets) { 14726 final boolean isInAsec; 14727 if (installOnExternalAsec(installFlags)) { 14728 /* Apps on SD card are always in ASEC containers. */ 14729 isInAsec = true; 14730 } else if (installForwardLocked(installFlags) 14731 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 14732 /* 14733 * Forward-locked apps are only in ASEC containers if they're the 14734 * new style 14735 */ 14736 isInAsec = true; 14737 } else { 14738 isInAsec = false; 14739 } 14740 14741 if (isInAsec) { 14742 return new AsecInstallArgs(codePath, instructionSets, 14743 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 14744 } else { 14745 return new FileInstallArgs(codePath, resourcePath, instructionSets); 14746 } 14747 } 14748 14749 static abstract class InstallArgs { 14750 /** @see InstallParams#origin */ 14751 final OriginInfo origin; 14752 /** @see InstallParams#move */ 14753 final MoveInfo move; 14754 14755 final IPackageInstallObserver2 observer; 14756 // Always refers to PackageManager flags only 14757 final int installFlags; 14758 final String installerPackageName; 14759 final String volumeUuid; 14760 final UserHandle user; 14761 final String abiOverride; 14762 final String[] installGrantPermissions; 14763 /** If non-null, drop an async trace when the install completes */ 14764 final String traceMethod; 14765 final int traceCookie; 14766 final Certificate[][] certificates; 14767 final int installReason; 14768 14769 // The list of instruction sets supported by this app. This is currently 14770 // only used during the rmdex() phase to clean up resources. We can get rid of this 14771 // if we move dex files under the common app path. 14772 /* nullable */ String[] instructionSets; 14773 14774 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 14775 int installFlags, String installerPackageName, String volumeUuid, 14776 UserHandle user, String[] instructionSets, 14777 String abiOverride, String[] installGrantPermissions, 14778 String traceMethod, int traceCookie, Certificate[][] certificates, 14779 int installReason) { 14780 this.origin = origin; 14781 this.move = move; 14782 this.installFlags = installFlags; 14783 this.observer = observer; 14784 this.installerPackageName = installerPackageName; 14785 this.volumeUuid = volumeUuid; 14786 this.user = user; 14787 this.instructionSets = instructionSets; 14788 this.abiOverride = abiOverride; 14789 this.installGrantPermissions = installGrantPermissions; 14790 this.traceMethod = traceMethod; 14791 this.traceCookie = traceCookie; 14792 this.certificates = certificates; 14793 this.installReason = installReason; 14794 } 14795 14796 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 14797 abstract int doPreInstall(int status); 14798 14799 /** 14800 * Rename package into final resting place. All paths on the given 14801 * scanned package should be updated to reflect the rename. 14802 */ 14803 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 14804 abstract int doPostInstall(int status, int uid); 14805 14806 /** @see PackageSettingBase#codePathString */ 14807 abstract String getCodePath(); 14808 /** @see PackageSettingBase#resourcePathString */ 14809 abstract String getResourcePath(); 14810 14811 // Need installer lock especially for dex file removal. 14812 abstract void cleanUpResourcesLI(); 14813 abstract boolean doPostDeleteLI(boolean delete); 14814 14815 /** 14816 * Called before the source arguments are copied. This is used mostly 14817 * for MoveParams when it needs to read the source file to put it in the 14818 * destination. 14819 */ 14820 int doPreCopy() { 14821 return PackageManager.INSTALL_SUCCEEDED; 14822 } 14823 14824 /** 14825 * Called after the source arguments are copied. This is used mostly for 14826 * MoveParams when it needs to read the source file to put it in the 14827 * destination. 14828 */ 14829 int doPostCopy(int uid) { 14830 return PackageManager.INSTALL_SUCCEEDED; 14831 } 14832 14833 protected boolean isFwdLocked() { 14834 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14835 } 14836 14837 protected boolean isExternalAsec() { 14838 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14839 } 14840 14841 protected boolean isEphemeral() { 14842 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14843 } 14844 14845 UserHandle getUser() { 14846 return user; 14847 } 14848 } 14849 14850 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 14851 if (!allCodePaths.isEmpty()) { 14852 if (instructionSets == null) { 14853 throw new IllegalStateException("instructionSet == null"); 14854 } 14855 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 14856 for (String codePath : allCodePaths) { 14857 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 14858 try { 14859 mInstaller.rmdex(codePath, dexCodeInstructionSet); 14860 } catch (InstallerException ignored) { 14861 } 14862 } 14863 } 14864 } 14865 } 14866 14867 /** 14868 * Logic to handle installation of non-ASEC applications, including copying 14869 * and renaming logic. 14870 */ 14871 class FileInstallArgs extends InstallArgs { 14872 private File codeFile; 14873 private File resourceFile; 14874 14875 // Example topology: 14876 // /data/app/com.example/base.apk 14877 // /data/app/com.example/split_foo.apk 14878 // /data/app/com.example/lib/arm/libfoo.so 14879 // /data/app/com.example/lib/arm64/libfoo.so 14880 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 14881 14882 /** New install */ 14883 FileInstallArgs(InstallParams params) { 14884 super(params.origin, params.move, params.observer, params.installFlags, 14885 params.installerPackageName, params.volumeUuid, 14886 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 14887 params.grantedRuntimePermissions, 14888 params.traceMethod, params.traceCookie, params.certificates, 14889 params.installReason); 14890 if (isFwdLocked()) { 14891 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 14892 } 14893 } 14894 14895 /** Existing install */ 14896 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 14897 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 14898 null, null, null, 0, null /*certificates*/, 14899 PackageManager.INSTALL_REASON_UNKNOWN); 14900 this.codeFile = (codePath != null) ? new File(codePath) : null; 14901 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 14902 } 14903 14904 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14905 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 14906 try { 14907 return doCopyApk(imcs, temp); 14908 } finally { 14909 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14910 } 14911 } 14912 14913 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14914 if (origin.staged) { 14915 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 14916 codeFile = origin.file; 14917 resourceFile = origin.file; 14918 return PackageManager.INSTALL_SUCCEEDED; 14919 } 14920 14921 try { 14922 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14923 final File tempDir = 14924 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 14925 codeFile = tempDir; 14926 resourceFile = tempDir; 14927 } catch (IOException e) { 14928 Slog.w(TAG, "Failed to create copy file: " + e); 14929 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 14930 } 14931 14932 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 14933 @Override 14934 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 14935 if (!FileUtils.isValidExtFilename(name)) { 14936 throw new IllegalArgumentException("Invalid filename: " + name); 14937 } 14938 try { 14939 final File file = new File(codeFile, name); 14940 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 14941 O_RDWR | O_CREAT, 0644); 14942 Os.chmod(file.getAbsolutePath(), 0644); 14943 return new ParcelFileDescriptor(fd); 14944 } catch (ErrnoException e) { 14945 throw new RemoteException("Failed to open: " + e.getMessage()); 14946 } 14947 } 14948 }; 14949 14950 int ret = PackageManager.INSTALL_SUCCEEDED; 14951 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 14952 if (ret != PackageManager.INSTALL_SUCCEEDED) { 14953 Slog.e(TAG, "Failed to copy package"); 14954 return ret; 14955 } 14956 14957 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 14958 NativeLibraryHelper.Handle handle = null; 14959 try { 14960 handle = NativeLibraryHelper.Handle.create(codeFile); 14961 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 14962 abiOverride); 14963 } catch (IOException e) { 14964 Slog.e(TAG, "Copying native libraries failed", e); 14965 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 14966 } finally { 14967 IoUtils.closeQuietly(handle); 14968 } 14969 14970 return ret; 14971 } 14972 14973 int doPreInstall(int status) { 14974 if (status != PackageManager.INSTALL_SUCCEEDED) { 14975 cleanUp(); 14976 } 14977 return status; 14978 } 14979 14980 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 14981 if (status != PackageManager.INSTALL_SUCCEEDED) { 14982 cleanUp(); 14983 return false; 14984 } 14985 14986 final File targetDir = codeFile.getParentFile(); 14987 final File beforeCodeFile = codeFile; 14988 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 14989 14990 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 14991 try { 14992 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 14993 } catch (ErrnoException e) { 14994 Slog.w(TAG, "Failed to rename", e); 14995 return false; 14996 } 14997 14998 if (!SELinux.restoreconRecursive(afterCodeFile)) { 14999 Slog.w(TAG, "Failed to restorecon"); 15000 return false; 15001 } 15002 15003 // Reflect the rename internally 15004 codeFile = afterCodeFile; 15005 resourceFile = afterCodeFile; 15006 15007 // Reflect the rename in scanned details 15008 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 15009 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 15010 afterCodeFile, pkg.baseCodePath)); 15011 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 15012 afterCodeFile, pkg.splitCodePaths)); 15013 15014 // Reflect the rename in app info 15015 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15016 pkg.setApplicationInfoCodePath(pkg.codePath); 15017 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15018 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15019 pkg.setApplicationInfoResourcePath(pkg.codePath); 15020 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15021 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15022 15023 return true; 15024 } 15025 15026 int doPostInstall(int status, int uid) { 15027 if (status != PackageManager.INSTALL_SUCCEEDED) { 15028 cleanUp(); 15029 } 15030 return status; 15031 } 15032 15033 @Override 15034 String getCodePath() { 15035 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 15036 } 15037 15038 @Override 15039 String getResourcePath() { 15040 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 15041 } 15042 15043 private boolean cleanUp() { 15044 if (codeFile == null || !codeFile.exists()) { 15045 return false; 15046 } 15047 15048 removeCodePathLI(codeFile); 15049 15050 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 15051 resourceFile.delete(); 15052 } 15053 15054 return true; 15055 } 15056 15057 void cleanUpResourcesLI() { 15058 // Try enumerating all code paths before deleting 15059 List<String> allCodePaths = Collections.EMPTY_LIST; 15060 if (codeFile != null && codeFile.exists()) { 15061 try { 15062 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 15063 allCodePaths = pkg.getAllCodePaths(); 15064 } catch (PackageParserException e) { 15065 // Ignored; we tried our best 15066 } 15067 } 15068 15069 cleanUp(); 15070 removeDexFiles(allCodePaths, instructionSets); 15071 } 15072 15073 boolean doPostDeleteLI(boolean delete) { 15074 // XXX err, shouldn't we respect the delete flag? 15075 cleanUpResourcesLI(); 15076 return true; 15077 } 15078 } 15079 15080 private boolean isAsecExternal(String cid) { 15081 final String asecPath = PackageHelper.getSdFilesystem(cid); 15082 return !asecPath.startsWith(mAsecInternalPath); 15083 } 15084 15085 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 15086 PackageManagerException { 15087 if (copyRet < 0) { 15088 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 15089 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 15090 throw new PackageManagerException(copyRet, message); 15091 } 15092 } 15093 } 15094 15095 /** 15096 * Extract the StorageManagerService "container ID" from the full code path of an 15097 * .apk. 15098 */ 15099 static String cidFromCodePath(String fullCodePath) { 15100 int eidx = fullCodePath.lastIndexOf("/"); 15101 String subStr1 = fullCodePath.substring(0, eidx); 15102 int sidx = subStr1.lastIndexOf("/"); 15103 return subStr1.substring(sidx+1, eidx); 15104 } 15105 15106 /** 15107 * Logic to handle installation of ASEC applications, including copying and 15108 * renaming logic. 15109 */ 15110 class AsecInstallArgs extends InstallArgs { 15111 static final String RES_FILE_NAME = "pkg.apk"; 15112 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 15113 15114 String cid; 15115 String packagePath; 15116 String resourcePath; 15117 15118 /** New install */ 15119 AsecInstallArgs(InstallParams params) { 15120 super(params.origin, params.move, params.observer, params.installFlags, 15121 params.installerPackageName, params.volumeUuid, 15122 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 15123 params.grantedRuntimePermissions, 15124 params.traceMethod, params.traceCookie, params.certificates, 15125 params.installReason); 15126 } 15127 15128 /** Existing install */ 15129 AsecInstallArgs(String fullCodePath, String[] instructionSets, 15130 boolean isExternal, boolean isForwardLocked) { 15131 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 15132 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 15133 instructionSets, null, null, null, 0, null /*certificates*/, 15134 PackageManager.INSTALL_REASON_UNKNOWN); 15135 // Hackily pretend we're still looking at a full code path 15136 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 15137 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 15138 } 15139 15140 // Extract cid from fullCodePath 15141 int eidx = fullCodePath.lastIndexOf("/"); 15142 String subStr1 = fullCodePath.substring(0, eidx); 15143 int sidx = subStr1.lastIndexOf("/"); 15144 cid = subStr1.substring(sidx+1, eidx); 15145 setMountPath(subStr1); 15146 } 15147 15148 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 15149 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 15150 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 15151 instructionSets, null, null, null, 0, null /*certificates*/, 15152 PackageManager.INSTALL_REASON_UNKNOWN); 15153 this.cid = cid; 15154 setMountPath(PackageHelper.getSdDir(cid)); 15155 } 15156 15157 void createCopyFile() { 15158 cid = mInstallerService.allocateExternalStageCidLegacy(); 15159 } 15160 15161 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 15162 if (origin.staged && origin.cid != null) { 15163 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 15164 cid = origin.cid; 15165 setMountPath(PackageHelper.getSdDir(cid)); 15166 return PackageManager.INSTALL_SUCCEEDED; 15167 } 15168 15169 if (temp) { 15170 createCopyFile(); 15171 } else { 15172 /* 15173 * Pre-emptively destroy the container since it's destroyed if 15174 * copying fails due to it existing anyway. 15175 */ 15176 PackageHelper.destroySdDir(cid); 15177 } 15178 15179 final String newMountPath = imcs.copyPackageToContainer( 15180 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 15181 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 15182 15183 if (newMountPath != null) { 15184 setMountPath(newMountPath); 15185 return PackageManager.INSTALL_SUCCEEDED; 15186 } else { 15187 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15188 } 15189 } 15190 15191 @Override 15192 String getCodePath() { 15193 return packagePath; 15194 } 15195 15196 @Override 15197 String getResourcePath() { 15198 return resourcePath; 15199 } 15200 15201 int doPreInstall(int status) { 15202 if (status != PackageManager.INSTALL_SUCCEEDED) { 15203 // Destroy container 15204 PackageHelper.destroySdDir(cid); 15205 } else { 15206 boolean mounted = PackageHelper.isContainerMounted(cid); 15207 if (!mounted) { 15208 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 15209 Process.SYSTEM_UID); 15210 if (newMountPath != null) { 15211 setMountPath(newMountPath); 15212 } else { 15213 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15214 } 15215 } 15216 } 15217 return status; 15218 } 15219 15220 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15221 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 15222 String newMountPath = null; 15223 if (PackageHelper.isContainerMounted(cid)) { 15224 // Unmount the container 15225 if (!PackageHelper.unMountSdDir(cid)) { 15226 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 15227 return false; 15228 } 15229 } 15230 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 15231 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 15232 " which might be stale. Will try to clean up."); 15233 // Clean up the stale container and proceed to recreate. 15234 if (!PackageHelper.destroySdDir(newCacheId)) { 15235 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 15236 return false; 15237 } 15238 // Successfully cleaned up stale container. Try to rename again. 15239 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 15240 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 15241 + " inspite of cleaning it up."); 15242 return false; 15243 } 15244 } 15245 if (!PackageHelper.isContainerMounted(newCacheId)) { 15246 Slog.w(TAG, "Mounting container " + newCacheId); 15247 newMountPath = PackageHelper.mountSdDir(newCacheId, 15248 getEncryptKey(), Process.SYSTEM_UID); 15249 } else { 15250 newMountPath = PackageHelper.getSdDir(newCacheId); 15251 } 15252 if (newMountPath == null) { 15253 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 15254 return false; 15255 } 15256 Log.i(TAG, "Succesfully renamed " + cid + 15257 " to " + newCacheId + 15258 " at new path: " + newMountPath); 15259 cid = newCacheId; 15260 15261 final File beforeCodeFile = new File(packagePath); 15262 setMountPath(newMountPath); 15263 final File afterCodeFile = new File(packagePath); 15264 15265 // Reflect the rename in scanned details 15266 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 15267 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 15268 afterCodeFile, pkg.baseCodePath)); 15269 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 15270 afterCodeFile, pkg.splitCodePaths)); 15271 15272 // Reflect the rename in app info 15273 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15274 pkg.setApplicationInfoCodePath(pkg.codePath); 15275 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15276 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15277 pkg.setApplicationInfoResourcePath(pkg.codePath); 15278 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15279 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15280 15281 return true; 15282 } 15283 15284 private void setMountPath(String mountPath) { 15285 final File mountFile = new File(mountPath); 15286 15287 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 15288 if (monolithicFile.exists()) { 15289 packagePath = monolithicFile.getAbsolutePath(); 15290 if (isFwdLocked()) { 15291 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 15292 } else { 15293 resourcePath = packagePath; 15294 } 15295 } else { 15296 packagePath = mountFile.getAbsolutePath(); 15297 resourcePath = packagePath; 15298 } 15299 } 15300 15301 int doPostInstall(int status, int uid) { 15302 if (status != PackageManager.INSTALL_SUCCEEDED) { 15303 cleanUp(); 15304 } else { 15305 final int groupOwner; 15306 final String protectedFile; 15307 if (isFwdLocked()) { 15308 groupOwner = UserHandle.getSharedAppGid(uid); 15309 protectedFile = RES_FILE_NAME; 15310 } else { 15311 groupOwner = -1; 15312 protectedFile = null; 15313 } 15314 15315 if (uid < Process.FIRST_APPLICATION_UID 15316 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 15317 Slog.e(TAG, "Failed to finalize " + cid); 15318 PackageHelper.destroySdDir(cid); 15319 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15320 } 15321 15322 boolean mounted = PackageHelper.isContainerMounted(cid); 15323 if (!mounted) { 15324 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 15325 } 15326 } 15327 return status; 15328 } 15329 15330 private void cleanUp() { 15331 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 15332 15333 // Destroy secure container 15334 PackageHelper.destroySdDir(cid); 15335 } 15336 15337 private List<String> getAllCodePaths() { 15338 final File codeFile = new File(getCodePath()); 15339 if (codeFile != null && codeFile.exists()) { 15340 try { 15341 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 15342 return pkg.getAllCodePaths(); 15343 } catch (PackageParserException e) { 15344 // Ignored; we tried our best 15345 } 15346 } 15347 return Collections.EMPTY_LIST; 15348 } 15349 15350 void cleanUpResourcesLI() { 15351 // Enumerate all code paths before deleting 15352 cleanUpResourcesLI(getAllCodePaths()); 15353 } 15354 15355 private void cleanUpResourcesLI(List<String> allCodePaths) { 15356 cleanUp(); 15357 removeDexFiles(allCodePaths, instructionSets); 15358 } 15359 15360 String getPackageName() { 15361 return getAsecPackageName(cid); 15362 } 15363 15364 boolean doPostDeleteLI(boolean delete) { 15365 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 15366 final List<String> allCodePaths = getAllCodePaths(); 15367 boolean mounted = PackageHelper.isContainerMounted(cid); 15368 if (mounted) { 15369 // Unmount first 15370 if (PackageHelper.unMountSdDir(cid)) { 15371 mounted = false; 15372 } 15373 } 15374 if (!mounted && delete) { 15375 cleanUpResourcesLI(allCodePaths); 15376 } 15377 return !mounted; 15378 } 15379 15380 @Override 15381 int doPreCopy() { 15382 if (isFwdLocked()) { 15383 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 15384 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 15385 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15386 } 15387 } 15388 15389 return PackageManager.INSTALL_SUCCEEDED; 15390 } 15391 15392 @Override 15393 int doPostCopy(int uid) { 15394 if (isFwdLocked()) { 15395 if (uid < Process.FIRST_APPLICATION_UID 15396 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 15397 RES_FILE_NAME)) { 15398 Slog.e(TAG, "Failed to finalize " + cid); 15399 PackageHelper.destroySdDir(cid); 15400 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15401 } 15402 } 15403 15404 return PackageManager.INSTALL_SUCCEEDED; 15405 } 15406 } 15407 15408 /** 15409 * Logic to handle movement of existing installed applications. 15410 */ 15411 class MoveInstallArgs extends InstallArgs { 15412 private File codeFile; 15413 private File resourceFile; 15414 15415 /** New install */ 15416 MoveInstallArgs(InstallParams params) { 15417 super(params.origin, params.move, params.observer, params.installFlags, 15418 params.installerPackageName, params.volumeUuid, 15419 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 15420 params.grantedRuntimePermissions, 15421 params.traceMethod, params.traceCookie, params.certificates, 15422 params.installReason); 15423 } 15424 15425 int copyApk(IMediaContainerService imcs, boolean temp) { 15426 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 15427 + move.fromUuid + " to " + move.toUuid); 15428 synchronized (mInstaller) { 15429 try { 15430 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 15431 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 15432 } catch (InstallerException e) { 15433 Slog.w(TAG, "Failed to move app", e); 15434 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 15435 } 15436 } 15437 15438 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 15439 resourceFile = codeFile; 15440 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 15441 15442 return PackageManager.INSTALL_SUCCEEDED; 15443 } 15444 15445 int doPreInstall(int status) { 15446 if (status != PackageManager.INSTALL_SUCCEEDED) { 15447 cleanUp(move.toUuid); 15448 } 15449 return status; 15450 } 15451 15452 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15453 if (status != PackageManager.INSTALL_SUCCEEDED) { 15454 cleanUp(move.toUuid); 15455 return false; 15456 } 15457 15458 // Reflect the move in app info 15459 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15460 pkg.setApplicationInfoCodePath(pkg.codePath); 15461 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15462 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15463 pkg.setApplicationInfoResourcePath(pkg.codePath); 15464 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15465 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15466 15467 return true; 15468 } 15469 15470 int doPostInstall(int status, int uid) { 15471 if (status == PackageManager.INSTALL_SUCCEEDED) { 15472 cleanUp(move.fromUuid); 15473 } else { 15474 cleanUp(move.toUuid); 15475 } 15476 return status; 15477 } 15478 15479 @Override 15480 String getCodePath() { 15481 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 15482 } 15483 15484 @Override 15485 String getResourcePath() { 15486 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 15487 } 15488 15489 private boolean cleanUp(String volumeUuid) { 15490 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 15491 move.dataAppName); 15492 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 15493 final int[] userIds = sUserManager.getUserIds(); 15494 synchronized (mInstallLock) { 15495 // Clean up both app data and code 15496 // All package moves are frozen until finished 15497 for (int userId : userIds) { 15498 try { 15499 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 15500 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 15501 } catch (InstallerException e) { 15502 Slog.w(TAG, String.valueOf(e)); 15503 } 15504 } 15505 removeCodePathLI(codeFile); 15506 } 15507 return true; 15508 } 15509 15510 void cleanUpResourcesLI() { 15511 throw new UnsupportedOperationException(); 15512 } 15513 15514 boolean doPostDeleteLI(boolean delete) { 15515 throw new UnsupportedOperationException(); 15516 } 15517 } 15518 15519 static String getAsecPackageName(String packageCid) { 15520 int idx = packageCid.lastIndexOf("-"); 15521 if (idx == -1) { 15522 return packageCid; 15523 } 15524 return packageCid.substring(0, idx); 15525 } 15526 15527 // Utility method used to create code paths based on package name and available index. 15528 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 15529 String idxStr = ""; 15530 int idx = 1; 15531 // Fall back to default value of idx=1 if prefix is not 15532 // part of oldCodePath 15533 if (oldCodePath != null) { 15534 String subStr = oldCodePath; 15535 // Drop the suffix right away 15536 if (suffix != null && subStr.endsWith(suffix)) { 15537 subStr = subStr.substring(0, subStr.length() - suffix.length()); 15538 } 15539 // If oldCodePath already contains prefix find out the 15540 // ending index to either increment or decrement. 15541 int sidx = subStr.lastIndexOf(prefix); 15542 if (sidx != -1) { 15543 subStr = subStr.substring(sidx + prefix.length()); 15544 if (subStr != null) { 15545 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 15546 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 15547 } 15548 try { 15549 idx = Integer.parseInt(subStr); 15550 if (idx <= 1) { 15551 idx++; 15552 } else { 15553 idx--; 15554 } 15555 } catch(NumberFormatException e) { 15556 } 15557 } 15558 } 15559 } 15560 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 15561 return prefix + idxStr; 15562 } 15563 15564 private File getNextCodePath(File targetDir, String packageName) { 15565 File result; 15566 SecureRandom random = new SecureRandom(); 15567 byte[] bytes = new byte[16]; 15568 do { 15569 random.nextBytes(bytes); 15570 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); 15571 result = new File(targetDir, packageName + "-" + suffix); 15572 } while (result.exists()); 15573 return result; 15574 } 15575 15576 // Utility method that returns the relative package path with respect 15577 // to the installation directory. Like say for /data/data/com.test-1.apk 15578 // string com.test-1 is returned. 15579 static String deriveCodePathName(String codePath) { 15580 if (codePath == null) { 15581 return null; 15582 } 15583 final File codeFile = new File(codePath); 15584 final String name = codeFile.getName(); 15585 if (codeFile.isDirectory()) { 15586 return name; 15587 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 15588 final int lastDot = name.lastIndexOf('.'); 15589 return name.substring(0, lastDot); 15590 } else { 15591 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 15592 return null; 15593 } 15594 } 15595 15596 static class PackageInstalledInfo { 15597 String name; 15598 int uid; 15599 // The set of users that originally had this package installed. 15600 int[] origUsers; 15601 // The set of users that now have this package installed. 15602 int[] newUsers; 15603 PackageParser.Package pkg; 15604 int returnCode; 15605 String returnMsg; 15606 PackageRemovedInfo removedInfo; 15607 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 15608 15609 public void setError(int code, String msg) { 15610 setReturnCode(code); 15611 setReturnMessage(msg); 15612 Slog.w(TAG, msg); 15613 } 15614 15615 public void setError(String msg, PackageParserException e) { 15616 setReturnCode(e.error); 15617 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 15618 Slog.w(TAG, msg, e); 15619 } 15620 15621 public void setError(String msg, PackageManagerException e) { 15622 returnCode = e.error; 15623 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 15624 Slog.w(TAG, msg, e); 15625 } 15626 15627 public void setReturnCode(int returnCode) { 15628 this.returnCode = returnCode; 15629 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 15630 for (int i = 0; i < childCount; i++) { 15631 addedChildPackages.valueAt(i).returnCode = returnCode; 15632 } 15633 } 15634 15635 private void setReturnMessage(String returnMsg) { 15636 this.returnMsg = returnMsg; 15637 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 15638 for (int i = 0; i < childCount; i++) { 15639 addedChildPackages.valueAt(i).returnMsg = returnMsg; 15640 } 15641 } 15642 15643 // In some error cases we want to convey more info back to the observer 15644 String origPackage; 15645 String origPermission; 15646 } 15647 15648 /* 15649 * Install a non-existing package. 15650 */ 15651 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 15652 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 15653 PackageInstalledInfo res, int installReason) { 15654 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 15655 15656 // Remember this for later, in case we need to rollback this install 15657 String pkgName = pkg.packageName; 15658 15659 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 15660 15661 synchronized(mPackages) { 15662 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName); 15663 if (renamedPackage != null) { 15664 // A package with the same name is already installed, though 15665 // it has been renamed to an older name. The package we 15666 // are trying to install should be installed as an update to 15667 // the existing one, but that has not been requested, so bail. 15668 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 15669 + " without first uninstalling package running as " 15670 + renamedPackage); 15671 return; 15672 } 15673 if (mPackages.containsKey(pkgName)) { 15674 // Don't allow installation over an existing package with the same name. 15675 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 15676 + " without first uninstalling."); 15677 return; 15678 } 15679 } 15680 15681 try { 15682 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 15683 System.currentTimeMillis(), user); 15684 15685 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason); 15686 15687 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 15688 prepareAppDataAfterInstallLIF(newPackage); 15689 15690 } else { 15691 // Remove package from internal structures, but keep around any 15692 // data that might have already existed 15693 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 15694 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 15695 } 15696 } catch (PackageManagerException e) { 15697 res.setError("Package couldn't be installed in " + pkg.codePath, e); 15698 } 15699 15700 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15701 } 15702 15703 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 15704 // Can't rotate keys during boot or if sharedUser. 15705 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 15706 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 15707 return false; 15708 } 15709 // app is using upgradeKeySets; make sure all are valid 15710 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15711 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 15712 for (int i = 0; i < upgradeKeySets.length; i++) { 15713 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 15714 Slog.wtf(TAG, "Package " 15715 + (oldPs.name != null ? oldPs.name : "<null>") 15716 + " contains upgrade-key-set reference to unknown key-set: " 15717 + upgradeKeySets[i] 15718 + " reverting to signatures check."); 15719 return false; 15720 } 15721 } 15722 return true; 15723 } 15724 15725 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 15726 // Upgrade keysets are being used. Determine if new package has a superset of the 15727 // required keys. 15728 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 15729 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15730 for (int i = 0; i < upgradeKeySets.length; i++) { 15731 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 15732 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 15733 return true; 15734 } 15735 } 15736 return false; 15737 } 15738 15739 private static void updateDigest(MessageDigest digest, File file) throws IOException { 15740 try (DigestInputStream digestStream = 15741 new DigestInputStream(new FileInputStream(file), digest)) { 15742 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 15743 } 15744 } 15745 15746 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 15747 UserHandle user, String installerPackageName, PackageInstalledInfo res, 15748 int installReason) { 15749 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 15750 15751 final PackageParser.Package oldPackage; 15752 final String pkgName = pkg.packageName; 15753 final int[] allUsers; 15754 final int[] installedUsers; 15755 15756 synchronized(mPackages) { 15757 oldPackage = mPackages.get(pkgName); 15758 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 15759 15760 // don't allow upgrade to target a release SDK from a pre-release SDK 15761 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 15762 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 15763 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 15764 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 15765 if (oldTargetsPreRelease 15766 && !newTargetsPreRelease 15767 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 15768 Slog.w(TAG, "Can't install package targeting released sdk"); 15769 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 15770 return; 15771 } 15772 15773 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15774 15775 // verify signatures are valid 15776 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 15777 if (!checkUpgradeKeySetLP(ps, pkg)) { 15778 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 15779 "New package not signed by keys specified by upgrade-keysets: " 15780 + pkgName); 15781 return; 15782 } 15783 } else { 15784 // default to original signature matching 15785 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 15786 != PackageManager.SIGNATURE_MATCH) { 15787 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 15788 "New package has a different signature: " + pkgName); 15789 return; 15790 } 15791 } 15792 15793 // don't allow a system upgrade unless the upgrade hash matches 15794 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 15795 byte[] digestBytes = null; 15796 try { 15797 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 15798 updateDigest(digest, new File(pkg.baseCodePath)); 15799 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 15800 for (String path : pkg.splitCodePaths) { 15801 updateDigest(digest, new File(path)); 15802 } 15803 } 15804 digestBytes = digest.digest(); 15805 } catch (NoSuchAlgorithmException | IOException e) { 15806 res.setError(INSTALL_FAILED_INVALID_APK, 15807 "Could not compute hash: " + pkgName); 15808 return; 15809 } 15810 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 15811 res.setError(INSTALL_FAILED_INVALID_APK, 15812 "New package fails restrict-update check: " + pkgName); 15813 return; 15814 } 15815 // retain upgrade restriction 15816 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 15817 } 15818 15819 // Check for shared user id changes 15820 String invalidPackageName = 15821 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 15822 if (invalidPackageName != null) { 15823 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 15824 "Package " + invalidPackageName + " tried to change user " 15825 + oldPackage.mSharedUserId); 15826 return; 15827 } 15828 15829 // In case of rollback, remember per-user/profile install state 15830 allUsers = sUserManager.getUserIds(); 15831 installedUsers = ps.queryInstalledUsers(allUsers, true); 15832 15833 // don't allow an upgrade from full to ephemeral 15834 if (isInstantApp) { 15835 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) { 15836 for (int currentUser : allUsers) { 15837 if (!ps.getInstantApp(currentUser)) { 15838 // can't downgrade from full to instant 15839 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName 15840 + " for user: " + currentUser); 15841 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 15842 return; 15843 } 15844 } 15845 } else if (!ps.getInstantApp(user.getIdentifier())) { 15846 // can't downgrade from full to instant 15847 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName 15848 + " for user: " + user.getIdentifier()); 15849 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 15850 return; 15851 } 15852 } 15853 } 15854 15855 // Update what is removed 15856 res.removedInfo = new PackageRemovedInfo(); 15857 res.removedInfo.uid = oldPackage.applicationInfo.uid; 15858 res.removedInfo.removedPackage = oldPackage.packageName; 15859 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null; 15860 res.removedInfo.isUpdate = true; 15861 res.removedInfo.origUsers = installedUsers; 15862 final PackageSetting ps = mSettings.getPackageLPr(pkgName); 15863 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length); 15864 for (int i = 0; i < installedUsers.length; i++) { 15865 final int userId = installedUsers[i]; 15866 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId)); 15867 } 15868 15869 final int childCount = (oldPackage.childPackages != null) 15870 ? oldPackage.childPackages.size() : 0; 15871 for (int i = 0; i < childCount; i++) { 15872 boolean childPackageUpdated = false; 15873 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 15874 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 15875 if (res.addedChildPackages != null) { 15876 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15877 if (childRes != null) { 15878 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 15879 childRes.removedInfo.removedPackage = childPkg.packageName; 15880 childRes.removedInfo.isUpdate = true; 15881 childRes.removedInfo.installReasons = res.removedInfo.installReasons; 15882 childPackageUpdated = true; 15883 } 15884 } 15885 if (!childPackageUpdated) { 15886 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 15887 childRemovedRes.removedPackage = childPkg.packageName; 15888 childRemovedRes.isUpdate = false; 15889 childRemovedRes.dataRemoved = true; 15890 synchronized (mPackages) { 15891 if (childPs != null) { 15892 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 15893 } 15894 } 15895 if (res.removedInfo.removedChildPackages == null) { 15896 res.removedInfo.removedChildPackages = new ArrayMap<>(); 15897 } 15898 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 15899 } 15900 } 15901 15902 boolean sysPkg = (isSystemApp(oldPackage)); 15903 if (sysPkg) { 15904 // Set the system/privileged flags as needed 15905 final boolean privileged = 15906 (oldPackage.applicationInfo.privateFlags 15907 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15908 final int systemPolicyFlags = policyFlags 15909 | PackageParser.PARSE_IS_SYSTEM 15910 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 15911 15912 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 15913 user, allUsers, installerPackageName, res, installReason); 15914 } else { 15915 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 15916 user, allUsers, installerPackageName, res, installReason); 15917 } 15918 } 15919 15920 public List<String> getPreviousCodePaths(String packageName) { 15921 final PackageSetting ps = mSettings.mPackages.get(packageName); 15922 final List<String> result = new ArrayList<String>(); 15923 if (ps != null && ps.oldCodePaths != null) { 15924 result.addAll(ps.oldCodePaths); 15925 } 15926 return result; 15927 } 15928 15929 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 15930 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 15931 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 15932 int installReason) { 15933 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 15934 + deletedPackage); 15935 15936 String pkgName = deletedPackage.packageName; 15937 boolean deletedPkg = true; 15938 boolean addedPkg = false; 15939 boolean updatedSettings = false; 15940 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 15941 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 15942 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 15943 15944 final long origUpdateTime = (pkg.mExtras != null) 15945 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 15946 15947 // First delete the existing package while retaining the data directory 15948 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 15949 res.removedInfo, true, pkg)) { 15950 // If the existing package wasn't successfully deleted 15951 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 15952 deletedPkg = false; 15953 } else { 15954 // Successfully deleted the old package; proceed with replace. 15955 15956 // If deleted package lived in a container, give users a chance to 15957 // relinquish resources before killing. 15958 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 15959 if (DEBUG_INSTALL) { 15960 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 15961 } 15962 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 15963 final ArrayList<String> pkgList = new ArrayList<String>(1); 15964 pkgList.add(deletedPackage.applicationInfo.packageName); 15965 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 15966 } 15967 15968 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 15969 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 15970 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 15971 15972 try { 15973 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 15974 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 15975 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 15976 installReason); 15977 15978 // Update the in-memory copy of the previous code paths. 15979 PackageSetting ps = mSettings.mPackages.get(pkgName); 15980 if (!killApp) { 15981 if (ps.oldCodePaths == null) { 15982 ps.oldCodePaths = new ArraySet<>(); 15983 } 15984 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 15985 if (deletedPackage.splitCodePaths != null) { 15986 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 15987 } 15988 } else { 15989 ps.oldCodePaths = null; 15990 } 15991 if (ps.childPackageNames != null) { 15992 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 15993 final String childPkgName = ps.childPackageNames.get(i); 15994 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 15995 childPs.oldCodePaths = ps.oldCodePaths; 15996 } 15997 } 15998 // set instant app status, but, only if it's explicitly specified 15999 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 16000 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0; 16001 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp); 16002 prepareAppDataAfterInstallLIF(newPackage); 16003 addedPkg = true; 16004 mDexManager.notifyPackageUpdated(newPackage.packageName, 16005 newPackage.baseCodePath, newPackage.splitCodePaths); 16006 } catch (PackageManagerException e) { 16007 res.setError("Package couldn't be installed in " + pkg.codePath, e); 16008 } 16009 } 16010 16011 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 16012 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 16013 16014 // Revert all internal state mutations and added folders for the failed install 16015 if (addedPkg) { 16016 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 16017 res.removedInfo, true, null); 16018 } 16019 16020 // Restore the old package 16021 if (deletedPkg) { 16022 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 16023 File restoreFile = new File(deletedPackage.codePath); 16024 // Parse old package 16025 boolean oldExternal = isExternal(deletedPackage); 16026 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 16027 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 16028 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 16029 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 16030 try { 16031 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 16032 null); 16033 } catch (PackageManagerException e) { 16034 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 16035 + e.getMessage()); 16036 return; 16037 } 16038 16039 synchronized (mPackages) { 16040 // Ensure the installer package name up to date 16041 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 16042 16043 // Update permissions for restored package 16044 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 16045 16046 mSettings.writeLPr(); 16047 } 16048 16049 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 16050 } 16051 } else { 16052 synchronized (mPackages) { 16053 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName); 16054 if (ps != null) { 16055 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16056 if (res.removedInfo.removedChildPackages != null) { 16057 final int childCount = res.removedInfo.removedChildPackages.size(); 16058 // Iterate in reverse as we may modify the collection 16059 for (int i = childCount - 1; i >= 0; i--) { 16060 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 16061 if (res.addedChildPackages.containsKey(childPackageName)) { 16062 res.removedInfo.removedChildPackages.removeAt(i); 16063 } else { 16064 PackageRemovedInfo childInfo = res.removedInfo 16065 .removedChildPackages.valueAt(i); 16066 childInfo.removedForAllUsers = mPackages.get( 16067 childInfo.removedPackage) == null; 16068 } 16069 } 16070 } 16071 } 16072 } 16073 } 16074 } 16075 16076 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 16077 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 16078 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 16079 int installReason) { 16080 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 16081 + ", old=" + deletedPackage); 16082 16083 final boolean disabledSystem; 16084 16085 // Remove existing system package 16086 removePackageLI(deletedPackage, true); 16087 16088 synchronized (mPackages) { 16089 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 16090 } 16091 if (!disabledSystem) { 16092 // We didn't need to disable the .apk as a current system package, 16093 // which means we are replacing another update that is already 16094 // installed. We need to make sure to delete the older one's .apk. 16095 res.removedInfo.args = createInstallArgsForExisting(0, 16096 deletedPackage.applicationInfo.getCodePath(), 16097 deletedPackage.applicationInfo.getResourcePath(), 16098 getAppDexInstructionSets(deletedPackage.applicationInfo)); 16099 } else { 16100 res.removedInfo.args = null; 16101 } 16102 16103 // Successfully disabled the old package. Now proceed with re-installation 16104 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 16105 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16106 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 16107 16108 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16109 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 16110 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 16111 16112 PackageParser.Package newPackage = null; 16113 try { 16114 // Add the package to the internal data structures 16115 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 16116 16117 // Set the update and install times 16118 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 16119 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 16120 System.currentTimeMillis()); 16121 16122 // Update the package dynamic state if succeeded 16123 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 16124 // Now that the install succeeded make sure we remove data 16125 // directories for any child package the update removed. 16126 final int deletedChildCount = (deletedPackage.childPackages != null) 16127 ? deletedPackage.childPackages.size() : 0; 16128 final int newChildCount = (newPackage.childPackages != null) 16129 ? newPackage.childPackages.size() : 0; 16130 for (int i = 0; i < deletedChildCount; i++) { 16131 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 16132 boolean childPackageDeleted = true; 16133 for (int j = 0; j < newChildCount; j++) { 16134 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 16135 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 16136 childPackageDeleted = false; 16137 break; 16138 } 16139 } 16140 if (childPackageDeleted) { 16141 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 16142 deletedChildPkg.packageName); 16143 if (ps != null && res.removedInfo.removedChildPackages != null) { 16144 PackageRemovedInfo removedChildRes = res.removedInfo 16145 .removedChildPackages.get(deletedChildPkg.packageName); 16146 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 16147 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 16148 } 16149 } 16150 } 16151 16152 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 16153 installReason); 16154 prepareAppDataAfterInstallLIF(newPackage); 16155 16156 mDexManager.notifyPackageUpdated(newPackage.packageName, 16157 newPackage.baseCodePath, newPackage.splitCodePaths); 16158 } 16159 } catch (PackageManagerException e) { 16160 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 16161 res.setError("Package couldn't be installed in " + pkg.codePath, e); 16162 } 16163 16164 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 16165 // Re installation failed. Restore old information 16166 // Remove new pkg information 16167 if (newPackage != null) { 16168 removeInstalledPackageLI(newPackage, true); 16169 } 16170 // Add back the old system package 16171 try { 16172 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 16173 } catch (PackageManagerException e) { 16174 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 16175 } 16176 16177 synchronized (mPackages) { 16178 if (disabledSystem) { 16179 enableSystemPackageLPw(deletedPackage); 16180 } 16181 16182 // Ensure the installer package name up to date 16183 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 16184 16185 // Update permissions for restored package 16186 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 16187 16188 mSettings.writeLPr(); 16189 } 16190 16191 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 16192 + " after failed upgrade"); 16193 } 16194 } 16195 16196 /** 16197 * Checks whether the parent or any of the child packages have a change shared 16198 * user. For a package to be a valid update the shred users of the parent and 16199 * the children should match. We may later support changing child shared users. 16200 * @param oldPkg The updated package. 16201 * @param newPkg The update package. 16202 * @return The shared user that change between the versions. 16203 */ 16204 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 16205 PackageParser.Package newPkg) { 16206 // Check parent shared user 16207 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 16208 return newPkg.packageName; 16209 } 16210 // Check child shared users 16211 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 16212 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 16213 for (int i = 0; i < newChildCount; i++) { 16214 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 16215 // If this child was present, did it have the same shared user? 16216 for (int j = 0; j < oldChildCount; j++) { 16217 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 16218 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 16219 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 16220 return newChildPkg.packageName; 16221 } 16222 } 16223 } 16224 return null; 16225 } 16226 16227 private void removeNativeBinariesLI(PackageSetting ps) { 16228 // Remove the lib path for the parent package 16229 if (ps != null) { 16230 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 16231 // Remove the lib path for the child packages 16232 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 16233 for (int i = 0; i < childCount; i++) { 16234 PackageSetting childPs = null; 16235 synchronized (mPackages) { 16236 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 16237 } 16238 if (childPs != null) { 16239 NativeLibraryHelper.removeNativeBinariesLI(childPs 16240 .legacyNativeLibraryPathString); 16241 } 16242 } 16243 } 16244 } 16245 16246 private void enableSystemPackageLPw(PackageParser.Package pkg) { 16247 // Enable the parent package 16248 mSettings.enableSystemPackageLPw(pkg.packageName); 16249 // Enable the child packages 16250 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16251 for (int i = 0; i < childCount; i++) { 16252 PackageParser.Package childPkg = pkg.childPackages.get(i); 16253 mSettings.enableSystemPackageLPw(childPkg.packageName); 16254 } 16255 } 16256 16257 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 16258 PackageParser.Package newPkg) { 16259 // Disable the parent package (parent always replaced) 16260 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 16261 // Disable the child packages 16262 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 16263 for (int i = 0; i < childCount; i++) { 16264 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 16265 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 16266 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 16267 } 16268 return disabled; 16269 } 16270 16271 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 16272 String installerPackageName) { 16273 // Enable the parent package 16274 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 16275 // Enable the child packages 16276 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16277 for (int i = 0; i < childCount; i++) { 16278 PackageParser.Package childPkg = pkg.childPackages.get(i); 16279 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 16280 } 16281 } 16282 16283 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 16284 // Collect all used permissions in the UID 16285 ArraySet<String> usedPermissions = new ArraySet<>(); 16286 final int packageCount = su.packages.size(); 16287 for (int i = 0; i < packageCount; i++) { 16288 PackageSetting ps = su.packages.valueAt(i); 16289 if (ps.pkg == null) { 16290 continue; 16291 } 16292 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 16293 for (int j = 0; j < requestedPermCount; j++) { 16294 String permission = ps.pkg.requestedPermissions.get(j); 16295 BasePermission bp = mSettings.mPermissions.get(permission); 16296 if (bp != null) { 16297 usedPermissions.add(permission); 16298 } 16299 } 16300 } 16301 16302 PermissionsState permissionsState = su.getPermissionsState(); 16303 // Prune install permissions 16304 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 16305 final int installPermCount = installPermStates.size(); 16306 for (int i = installPermCount - 1; i >= 0; i--) { 16307 PermissionState permissionState = installPermStates.get(i); 16308 if (!usedPermissions.contains(permissionState.getName())) { 16309 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 16310 if (bp != null) { 16311 permissionsState.revokeInstallPermission(bp); 16312 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 16313 PackageManager.MASK_PERMISSION_FLAGS, 0); 16314 } 16315 } 16316 } 16317 16318 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 16319 16320 // Prune runtime permissions 16321 for (int userId : allUserIds) { 16322 List<PermissionState> runtimePermStates = permissionsState 16323 .getRuntimePermissionStates(userId); 16324 final int runtimePermCount = runtimePermStates.size(); 16325 for (int i = runtimePermCount - 1; i >= 0; i--) { 16326 PermissionState permissionState = runtimePermStates.get(i); 16327 if (!usedPermissions.contains(permissionState.getName())) { 16328 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 16329 if (bp != null) { 16330 permissionsState.revokeRuntimePermission(bp, userId); 16331 permissionsState.updatePermissionFlags(bp, userId, 16332 PackageManager.MASK_PERMISSION_FLAGS, 0); 16333 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 16334 runtimePermissionChangedUserIds, userId); 16335 } 16336 } 16337 } 16338 } 16339 16340 return runtimePermissionChangedUserIds; 16341 } 16342 16343 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 16344 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) { 16345 // Update the parent package setting 16346 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 16347 res, user, installReason); 16348 // Update the child packages setting 16349 final int childCount = (newPackage.childPackages != null) 16350 ? newPackage.childPackages.size() : 0; 16351 for (int i = 0; i < childCount; i++) { 16352 PackageParser.Package childPackage = newPackage.childPackages.get(i); 16353 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 16354 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 16355 childRes.origUsers, childRes, user, installReason); 16356 } 16357 } 16358 16359 private void updateSettingsInternalLI(PackageParser.Package newPackage, 16360 String installerPackageName, int[] allUsers, int[] installedForUsers, 16361 PackageInstalledInfo res, UserHandle user, int installReason) { 16362 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 16363 16364 String pkgName = newPackage.packageName; 16365 synchronized (mPackages) { 16366 //write settings. the installStatus will be incomplete at this stage. 16367 //note that the new package setting would have already been 16368 //added to mPackages. It hasn't been persisted yet. 16369 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 16370 // TODO: Remove this write? It's also written at the end of this method 16371 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 16372 mSettings.writeLPr(); 16373 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16374 } 16375 16376 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 16377 synchronized (mPackages) { 16378 updatePermissionsLPw(newPackage.packageName, newPackage, 16379 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 16380 ? UPDATE_PERMISSIONS_ALL : 0)); 16381 // For system-bundled packages, we assume that installing an upgraded version 16382 // of the package implies that the user actually wants to run that new code, 16383 // so we enable the package. 16384 PackageSetting ps = mSettings.mPackages.get(pkgName); 16385 final int userId = user.getIdentifier(); 16386 if (ps != null) { 16387 if (isSystemApp(newPackage)) { 16388 if (DEBUG_INSTALL) { 16389 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 16390 } 16391 // Enable system package for requested users 16392 if (res.origUsers != null) { 16393 for (int origUserId : res.origUsers) { 16394 if (userId == UserHandle.USER_ALL || userId == origUserId) { 16395 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 16396 origUserId, installerPackageName); 16397 } 16398 } 16399 } 16400 // Also convey the prior install/uninstall state 16401 if (allUsers != null && installedForUsers != null) { 16402 for (int currentUserId : allUsers) { 16403 final boolean installed = ArrayUtils.contains( 16404 installedForUsers, currentUserId); 16405 if (DEBUG_INSTALL) { 16406 Slog.d(TAG, " user " + currentUserId + " => " + installed); 16407 } 16408 ps.setInstalled(installed, currentUserId); 16409 } 16410 // these install state changes will be persisted in the 16411 // upcoming call to mSettings.writeLPr(). 16412 } 16413 } 16414 // It's implied that when a user requests installation, they want the app to be 16415 // installed and enabled. 16416 if (userId != UserHandle.USER_ALL) { 16417 ps.setInstalled(true, userId); 16418 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 16419 } 16420 16421 // When replacing an existing package, preserve the original install reason for all 16422 // users that had the package installed before. 16423 final Set<Integer> previousUserIds = new ArraySet<>(); 16424 if (res.removedInfo != null && res.removedInfo.installReasons != null) { 16425 final int installReasonCount = res.removedInfo.installReasons.size(); 16426 for (int i = 0; i < installReasonCount; i++) { 16427 final int previousUserId = res.removedInfo.installReasons.keyAt(i); 16428 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i); 16429 ps.setInstallReason(previousInstallReason, previousUserId); 16430 previousUserIds.add(previousUserId); 16431 } 16432 } 16433 16434 // Set install reason for users that are having the package newly installed. 16435 if (userId == UserHandle.USER_ALL) { 16436 for (int currentUserId : sUserManager.getUserIds()) { 16437 if (!previousUserIds.contains(currentUserId)) { 16438 ps.setInstallReason(installReason, currentUserId); 16439 } 16440 } 16441 } else if (!previousUserIds.contains(userId)) { 16442 ps.setInstallReason(installReason, userId); 16443 } 16444 mSettings.writeKernelMappingLPr(ps); 16445 } 16446 res.name = pkgName; 16447 res.uid = newPackage.applicationInfo.uid; 16448 res.pkg = newPackage; 16449 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 16450 mSettings.setInstallerPackageName(pkgName, installerPackageName); 16451 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16452 //to update install status 16453 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 16454 mSettings.writeLPr(); 16455 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16456 } 16457 16458 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16459 } 16460 16461 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 16462 try { 16463 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 16464 installPackageLI(args, res); 16465 } finally { 16466 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16467 } 16468 } 16469 16470 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 16471 final int installFlags = args.installFlags; 16472 final String installerPackageName = args.installerPackageName; 16473 final String volumeUuid = args.volumeUuid; 16474 final File tmpPackageFile = new File(args.getCodePath()); 16475 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 16476 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 16477 || (args.volumeUuid != null)); 16478 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); 16479 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); 16480 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 16481 boolean replace = false; 16482 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 16483 if (args.move != null) { 16484 // moving a complete application; perform an initial scan on the new install location 16485 scanFlags |= SCAN_INITIAL; 16486 } 16487 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 16488 scanFlags |= SCAN_DONT_KILL_APP; 16489 } 16490 if (instantApp) { 16491 scanFlags |= SCAN_AS_INSTANT_APP; 16492 } 16493 if (fullApp) { 16494 scanFlags |= SCAN_AS_FULL_APP; 16495 } 16496 16497 // Result object to be returned 16498 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16499 16500 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 16501 16502 // Sanity check 16503 if (instantApp && (forwardLocked || onExternal)) { 16504 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 16505 + " external=" + onExternal); 16506 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 16507 return; 16508 } 16509 16510 // Retrieve PackageSettings and parse package 16511 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 16512 | PackageParser.PARSE_ENFORCE_CODE 16513 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 16514 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 16515 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0) 16516 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 16517 PackageParser pp = new PackageParser(); 16518 pp.setSeparateProcesses(mSeparateProcesses); 16519 pp.setDisplayMetrics(mMetrics); 16520 pp.setCallback(mPackageParserCallback); 16521 16522 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 16523 final PackageParser.Package pkg; 16524 try { 16525 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 16526 } catch (PackageParserException e) { 16527 res.setError("Failed parse during installPackageLI", e); 16528 return; 16529 } finally { 16530 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16531 } 16532 16533 // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2 16534 if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) { 16535 Slog.w(TAG, "Instant app package " + pkg.packageName 16536 + " does not target O, this will be a fatal error."); 16537 // STOPSHIP: Make this a fatal error 16538 pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O; 16539 } 16540 if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) { 16541 Slog.w(TAG, "Instant app package " + pkg.packageName 16542 + " does not target targetSandboxVersion 2, this will be a fatal error."); 16543 // STOPSHIP: Make this a fatal error 16544 pkg.applicationInfo.targetSandboxVersion = 2; 16545 } 16546 16547 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16548 // Static shared libraries have synthetic package names 16549 renameStaticSharedLibraryPackage(pkg); 16550 16551 // No static shared libs on external storage 16552 if (onExternal) { 16553 Slog.i(TAG, "Static shared libs can only be installed on internal storage."); 16554 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 16555 "Packages declaring static-shared libs cannot be updated"); 16556 return; 16557 } 16558 } 16559 16560 // If we are installing a clustered package add results for the children 16561 if (pkg.childPackages != null) { 16562 synchronized (mPackages) { 16563 final int childCount = pkg.childPackages.size(); 16564 for (int i = 0; i < childCount; i++) { 16565 PackageParser.Package childPkg = pkg.childPackages.get(i); 16566 PackageInstalledInfo childRes = new PackageInstalledInfo(); 16567 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16568 childRes.pkg = childPkg; 16569 childRes.name = childPkg.packageName; 16570 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 16571 if (childPs != null) { 16572 childRes.origUsers = childPs.queryInstalledUsers( 16573 sUserManager.getUserIds(), true); 16574 } 16575 if ((mPackages.containsKey(childPkg.packageName))) { 16576 childRes.removedInfo = new PackageRemovedInfo(); 16577 childRes.removedInfo.removedPackage = childPkg.packageName; 16578 } 16579 if (res.addedChildPackages == null) { 16580 res.addedChildPackages = new ArrayMap<>(); 16581 } 16582 res.addedChildPackages.put(childPkg.packageName, childRes); 16583 } 16584 } 16585 } 16586 16587 // If package doesn't declare API override, mark that we have an install 16588 // time CPU ABI override. 16589 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 16590 pkg.cpuAbiOverride = args.abiOverride; 16591 } 16592 16593 String pkgName = res.name = pkg.packageName; 16594 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 16595 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 16596 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 16597 return; 16598 } 16599 } 16600 16601 try { 16602 // either use what we've been given or parse directly from the APK 16603 if (args.certificates != null) { 16604 try { 16605 PackageParser.populateCertificates(pkg, args.certificates); 16606 } catch (PackageParserException e) { 16607 // there was something wrong with the certificates we were given; 16608 // try to pull them from the APK 16609 PackageParser.collectCertificates(pkg, parseFlags); 16610 } 16611 } else { 16612 PackageParser.collectCertificates(pkg, parseFlags); 16613 } 16614 } catch (PackageParserException e) { 16615 res.setError("Failed collect during installPackageLI", e); 16616 return; 16617 } 16618 16619 // Get rid of all references to package scan path via parser. 16620 pp = null; 16621 String oldCodePath = null; 16622 boolean systemApp = false; 16623 synchronized (mPackages) { 16624 // Check if installing already existing package 16625 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 16626 String oldName = mSettings.getRenamedPackageLPr(pkgName); 16627 if (pkg.mOriginalPackages != null 16628 && pkg.mOriginalPackages.contains(oldName) 16629 && mPackages.containsKey(oldName)) { 16630 // This package is derived from an original package, 16631 // and this device has been updating from that original 16632 // name. We must continue using the original name, so 16633 // rename the new package here. 16634 pkg.setPackageName(oldName); 16635 pkgName = pkg.packageName; 16636 replace = true; 16637 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 16638 + oldName + " pkgName=" + pkgName); 16639 } else if (mPackages.containsKey(pkgName)) { 16640 // This package, under its official name, already exists 16641 // on the device; we should replace it. 16642 replace = true; 16643 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 16644 } 16645 16646 // Child packages are installed through the parent package 16647 if (pkg.parentPackage != null) { 16648 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 16649 "Package " + pkg.packageName + " is child of package " 16650 + pkg.parentPackage.parentPackage + ". Child packages " 16651 + "can be updated only through the parent package."); 16652 return; 16653 } 16654 16655 if (replace) { 16656 // Prevent apps opting out from runtime permissions 16657 PackageParser.Package oldPackage = mPackages.get(pkgName); 16658 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 16659 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 16660 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 16661 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 16662 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 16663 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 16664 + " doesn't support runtime permissions but the old" 16665 + " target SDK " + oldTargetSdk + " does."); 16666 return; 16667 } 16668 16669 // Prevent installing of child packages 16670 if (oldPackage.parentPackage != null) { 16671 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 16672 "Package " + pkg.packageName + " is child of package " 16673 + oldPackage.parentPackage + ". Child packages " 16674 + "can be updated only through the parent package."); 16675 return; 16676 } 16677 } 16678 } 16679 16680 PackageSetting ps = mSettings.mPackages.get(pkgName); 16681 if (ps != null) { 16682 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 16683 16684 // Static shared libs have same package with different versions where 16685 // we internally use a synthetic package name to allow multiple versions 16686 // of the same package, therefore we need to compare signatures against 16687 // the package setting for the latest library version. 16688 PackageSetting signatureCheckPs = ps; 16689 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16690 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg); 16691 if (libraryEntry != null) { 16692 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk); 16693 } 16694 } 16695 16696 // Quick sanity check that we're signed correctly if updating; 16697 // we'll check this again later when scanning, but we want to 16698 // bail early here before tripping over redefined permissions. 16699 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) { 16700 if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) { 16701 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 16702 + pkg.packageName + " upgrade keys do not match the " 16703 + "previously installed version"); 16704 return; 16705 } 16706 } else { 16707 try { 16708 verifySignaturesLP(signatureCheckPs, pkg); 16709 } catch (PackageManagerException e) { 16710 res.setError(e.error, e.getMessage()); 16711 return; 16712 } 16713 } 16714 16715 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 16716 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 16717 systemApp = (ps.pkg.applicationInfo.flags & 16718 ApplicationInfo.FLAG_SYSTEM) != 0; 16719 } 16720 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 16721 } 16722 16723 int N = pkg.permissions.size(); 16724 for (int i = N-1; i >= 0; i--) { 16725 PackageParser.Permission perm = pkg.permissions.get(i); 16726 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 16727 16728 // Don't allow anyone but the platform to define ephemeral permissions. 16729 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0 16730 && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { 16731 Slog.w(TAG, "Package " + pkg.packageName 16732 + " attempting to delcare ephemeral permission " 16733 + perm.info.name + "; Removing ephemeral."); 16734 perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL; 16735 } 16736 // Check whether the newly-scanned package wants to define an already-defined perm 16737 if (bp != null) { 16738 // If the defining package is signed with our cert, it's okay. This 16739 // also includes the "updating the same package" case, of course. 16740 // "updating same package" could also involve key-rotation. 16741 final boolean sigsOk; 16742 if (bp.sourcePackage.equals(pkg.packageName) 16743 && (bp.packageSetting instanceof PackageSetting) 16744 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 16745 scanFlags))) { 16746 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 16747 } else { 16748 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 16749 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 16750 } 16751 if (!sigsOk) { 16752 // If the owning package is the system itself, we log but allow 16753 // install to proceed; we fail the install on all other permission 16754 // redefinitions. 16755 if (!bp.sourcePackage.equals("android")) { 16756 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 16757 + pkg.packageName + " attempting to redeclare permission " 16758 + perm.info.name + " already owned by " + bp.sourcePackage); 16759 res.origPermission = perm.info.name; 16760 res.origPackage = bp.sourcePackage; 16761 return; 16762 } else { 16763 Slog.w(TAG, "Package " + pkg.packageName 16764 + " attempting to redeclare system permission " 16765 + perm.info.name + "; ignoring new declaration"); 16766 pkg.permissions.remove(i); 16767 } 16768 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { 16769 // Prevent apps to change protection level to dangerous from any other 16770 // type as this would allow a privilege escalation where an app adds a 16771 // normal/signature permission in other app's group and later redefines 16772 // it as dangerous leading to the group auto-grant. 16773 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) 16774 == PermissionInfo.PROTECTION_DANGEROUS) { 16775 if (bp != null && !bp.isRuntime()) { 16776 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a " 16777 + "non-runtime permission " + perm.info.name 16778 + " to runtime; keeping old protection level"); 16779 perm.info.protectionLevel = bp.protectionLevel; 16780 } 16781 } 16782 } 16783 } 16784 } 16785 } 16786 16787 if (systemApp) { 16788 if (onExternal) { 16789 // Abort update; system app can't be replaced with app on sdcard 16790 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 16791 "Cannot install updates to system apps on sdcard"); 16792 return; 16793 } else if (instantApp) { 16794 // Abort update; system app can't be replaced with an instant app 16795 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID, 16796 "Cannot update a system app with an instant app"); 16797 return; 16798 } 16799 } 16800 16801 if (args.move != null) { 16802 // We did an in-place move, so dex is ready to roll 16803 scanFlags |= SCAN_NO_DEX; 16804 scanFlags |= SCAN_MOVE; 16805 16806 synchronized (mPackages) { 16807 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16808 if (ps == null) { 16809 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 16810 "Missing settings for moved package " + pkgName); 16811 } 16812 16813 // We moved the entire application as-is, so bring over the 16814 // previously derived ABI information. 16815 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 16816 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 16817 } 16818 16819 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 16820 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 16821 scanFlags |= SCAN_NO_DEX; 16822 16823 try { 16824 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 16825 args.abiOverride : pkg.cpuAbiOverride); 16826 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 16827 true /*extractLibs*/, mAppLib32InstallDir); 16828 } catch (PackageManagerException pme) { 16829 Slog.e(TAG, "Error deriving application ABI", pme); 16830 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 16831 return; 16832 } 16833 16834 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 16835 // Do not run PackageDexOptimizer through the local performDexOpt 16836 // method because `pkg` may not be in `mPackages` yet. 16837 // 16838 // Also, don't fail application installs if the dexopt step fails. 16839 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 16840 null /* instructionSets */, false /* checkProfiles */, 16841 getCompilerFilterForReason(REASON_INSTALL), 16842 getOrCreateCompilerPackageStats(pkg), 16843 mDexManager.isUsedByOtherApps(pkg.packageName)); 16844 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16845 16846 // Notify BackgroundDexOptJobService that the package has been changed. 16847 // If this is an update of a package which used to fail to compile, 16848 // BDOS will remove it from its blacklist. 16849 // TODO: Layering violation 16850 BackgroundDexOptJobService.notifyPackageChanged(pkg.packageName); 16851 } 16852 16853 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 16854 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 16855 return; 16856 } 16857 16858 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 16859 16860 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 16861 "installPackageLI")) { 16862 if (replace) { 16863 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16864 // Static libs have a synthetic package name containing the version 16865 // and cannot be updated as an update would get a new package name, 16866 // unless this is the exact same version code which is useful for 16867 // development. 16868 PackageParser.Package existingPkg = mPackages.get(pkg.packageName); 16869 if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) { 16870 res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring " 16871 + "static-shared libs cannot be updated"); 16872 return; 16873 } 16874 } 16875 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 16876 installerPackageName, res, args.installReason); 16877 } else { 16878 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 16879 args.user, installerPackageName, volumeUuid, res, args.installReason); 16880 } 16881 } 16882 synchronized (mPackages) { 16883 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16884 if (ps != null) { 16885 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 16886 } 16887 16888 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16889 for (int i = 0; i < childCount; i++) { 16890 PackageParser.Package childPkg = pkg.childPackages.get(i); 16891 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 16892 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 16893 if (childPs != null) { 16894 childRes.newUsers = childPs.queryInstalledUsers( 16895 sUserManager.getUserIds(), true); 16896 } 16897 } 16898 16899 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 16900 updateSequenceNumberLP(pkgName, res.newUsers); 16901 } 16902 } 16903 } 16904 16905 private void startIntentFilterVerifications(int userId, boolean replacing, 16906 PackageParser.Package pkg) { 16907 if (mIntentFilterVerifierComponent == null) { 16908 Slog.w(TAG, "No IntentFilter verification will not be done as " 16909 + "there is no IntentFilterVerifier available!"); 16910 return; 16911 } 16912 16913 final int verifierUid = getPackageUid( 16914 mIntentFilterVerifierComponent.getPackageName(), 16915 MATCH_DEBUG_TRIAGED_MISSING, 16916 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 16917 16918 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 16919 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 16920 mHandler.sendMessage(msg); 16921 16922 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16923 for (int i = 0; i < childCount; i++) { 16924 PackageParser.Package childPkg = pkg.childPackages.get(i); 16925 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 16926 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 16927 mHandler.sendMessage(msg); 16928 } 16929 } 16930 16931 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 16932 PackageParser.Package pkg) { 16933 int size = pkg.activities.size(); 16934 if (size == 0) { 16935 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 16936 "No activity, so no need to verify any IntentFilter!"); 16937 return; 16938 } 16939 16940 final boolean hasDomainURLs = hasDomainURLs(pkg); 16941 if (!hasDomainURLs) { 16942 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 16943 "No domain URLs, so no need to verify any IntentFilter!"); 16944 return; 16945 } 16946 16947 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 16948 + " if any IntentFilter from the " + size 16949 + " Activities needs verification ..."); 16950 16951 int count = 0; 16952 final String packageName = pkg.packageName; 16953 16954 synchronized (mPackages) { 16955 // If this is a new install and we see that we've already run verification for this 16956 // package, we have nothing to do: it means the state was restored from backup. 16957 if (!replacing) { 16958 IntentFilterVerificationInfo ivi = 16959 mSettings.getIntentFilterVerificationLPr(packageName); 16960 if (ivi != null) { 16961 if (DEBUG_DOMAIN_VERIFICATION) { 16962 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 16963 + ivi.getStatusString()); 16964 } 16965 return; 16966 } 16967 } 16968 16969 // If any filters need to be verified, then all need to be. 16970 boolean needToVerify = false; 16971 for (PackageParser.Activity a : pkg.activities) { 16972 for (ActivityIntentInfo filter : a.intents) { 16973 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 16974 if (DEBUG_DOMAIN_VERIFICATION) { 16975 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 16976 } 16977 needToVerify = true; 16978 break; 16979 } 16980 } 16981 } 16982 16983 if (needToVerify) { 16984 final int verificationId = mIntentFilterVerificationToken++; 16985 for (PackageParser.Activity a : pkg.activities) { 16986 for (ActivityIntentInfo filter : a.intents) { 16987 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 16988 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 16989 "Verification needed for IntentFilter:" + filter.toString()); 16990 mIntentFilterVerifier.addOneIntentFilterVerification( 16991 verifierUid, userId, verificationId, filter, packageName); 16992 count++; 16993 } 16994 } 16995 } 16996 } 16997 } 16998 16999 if (count > 0) { 17000 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 17001 + " IntentFilter verification" + (count > 1 ? "s" : "") 17002 + " for userId:" + userId); 17003 mIntentFilterVerifier.startVerifications(userId); 17004 } else { 17005 if (DEBUG_DOMAIN_VERIFICATION) { 17006 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 17007 } 17008 } 17009 } 17010 17011 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 17012 final ComponentName cn = filter.activity.getComponentName(); 17013 final String packageName = cn.getPackageName(); 17014 17015 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 17016 packageName); 17017 if (ivi == null) { 17018 return true; 17019 } 17020 int status = ivi.getStatus(); 17021 switch (status) { 17022 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 17023 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 17024 return true; 17025 17026 default: 17027 // Nothing to do 17028 return false; 17029 } 17030 } 17031 17032 private static boolean isMultiArch(ApplicationInfo info) { 17033 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 17034 } 17035 17036 private static boolean isExternal(PackageParser.Package pkg) { 17037 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 17038 } 17039 17040 private static boolean isExternal(PackageSetting ps) { 17041 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 17042 } 17043 17044 private static boolean isSystemApp(PackageParser.Package pkg) { 17045 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 17046 } 17047 17048 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 17049 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 17050 } 17051 17052 private static boolean hasDomainURLs(PackageParser.Package pkg) { 17053 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 17054 } 17055 17056 private static boolean isSystemApp(PackageSetting ps) { 17057 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 17058 } 17059 17060 private static boolean isUpdatedSystemApp(PackageSetting ps) { 17061 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 17062 } 17063 17064 private int packageFlagsToInstallFlags(PackageSetting ps) { 17065 int installFlags = 0; 17066 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 17067 // This existing package was an external ASEC install when we have 17068 // the external flag without a UUID 17069 installFlags |= PackageManager.INSTALL_EXTERNAL; 17070 } 17071 if (ps.isForwardLocked()) { 17072 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 17073 } 17074 return installFlags; 17075 } 17076 17077 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 17078 if (isExternal(pkg)) { 17079 if (TextUtils.isEmpty(pkg.volumeUuid)) { 17080 return StorageManager.UUID_PRIMARY_PHYSICAL; 17081 } else { 17082 return pkg.volumeUuid; 17083 } 17084 } else { 17085 return StorageManager.UUID_PRIVATE_INTERNAL; 17086 } 17087 } 17088 17089 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 17090 if (isExternal(pkg)) { 17091 if (TextUtils.isEmpty(pkg.volumeUuid)) { 17092 return mSettings.getExternalVersion(); 17093 } else { 17094 return mSettings.findOrCreateVersion(pkg.volumeUuid); 17095 } 17096 } else { 17097 return mSettings.getInternalVersion(); 17098 } 17099 } 17100 17101 private void deleteTempPackageFiles() { 17102 final FilenameFilter filter = new FilenameFilter() { 17103 public boolean accept(File dir, String name) { 17104 return name.startsWith("vmdl") && name.endsWith(".tmp"); 17105 } 17106 }; 17107 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 17108 file.delete(); 17109 } 17110 } 17111 17112 @Override 17113 public void deletePackageAsUser(String packageName, int versionCode, 17114 IPackageDeleteObserver observer, int userId, int flags) { 17115 deletePackageVersioned(new VersionedPackage(packageName, versionCode), 17116 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags); 17117 } 17118 17119 @Override 17120 public void deletePackageVersioned(VersionedPackage versionedPackage, 17121 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 17122 mContext.enforceCallingOrSelfPermission( 17123 android.Manifest.permission.DELETE_PACKAGES, null); 17124 Preconditions.checkNotNull(versionedPackage); 17125 Preconditions.checkNotNull(observer); 17126 Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(), 17127 PackageManager.VERSION_CODE_HIGHEST, 17128 Integer.MAX_VALUE, "versionCode must be >= -1"); 17129 17130 final String packageName = versionedPackage.getPackageName(); 17131 // TODO: We will change version code to long, so in the new API it is long 17132 final int versionCode = (int) versionedPackage.getVersionCode(); 17133 final String internalPackageName; 17134 synchronized (mPackages) { 17135 // Normalize package name to handle renamed packages and static libs 17136 internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(), 17137 // TODO: We will change version code to long, so in the new API it is long 17138 (int) versionedPackage.getVersionCode()); 17139 } 17140 17141 final int uid = Binder.getCallingUid(); 17142 if (!isOrphaned(internalPackageName) 17143 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) { 17144 try { 17145 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 17146 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 17147 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 17148 observer.onUserActionRequired(intent); 17149 } catch (RemoteException re) { 17150 } 17151 return; 17152 } 17153 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 17154 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 17155 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 17156 mContext.enforceCallingOrSelfPermission( 17157 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 17158 "deletePackage for user " + userId); 17159 } 17160 17161 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 17162 try { 17163 observer.onPackageDeleted(packageName, 17164 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 17165 } catch (RemoteException re) { 17166 } 17167 return; 17168 } 17169 17170 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) { 17171 try { 17172 observer.onPackageDeleted(packageName, 17173 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 17174 } catch (RemoteException re) { 17175 } 17176 return; 17177 } 17178 17179 if (DEBUG_REMOVE) { 17180 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId 17181 + " deleteAllUsers: " + deleteAllUsers + " version=" 17182 + (versionCode == PackageManager.VERSION_CODE_HIGHEST 17183 ? "VERSION_CODE_HIGHEST" : versionCode)); 17184 } 17185 // Queue up an async operation since the package deletion may take a little while. 17186 mHandler.post(new Runnable() { 17187 public void run() { 17188 mHandler.removeCallbacks(this); 17189 int returnCode; 17190 if (!deleteAllUsers) { 17191 returnCode = deletePackageX(internalPackageName, versionCode, 17192 userId, deleteFlags); 17193 } else { 17194 int[] blockUninstallUserIds = getBlockUninstallForUsers( 17195 internalPackageName, users); 17196 // If nobody is blocking uninstall, proceed with delete for all users 17197 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 17198 returnCode = deletePackageX(internalPackageName, versionCode, 17199 userId, deleteFlags); 17200 } else { 17201 // Otherwise uninstall individually for users with blockUninstalls=false 17202 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 17203 for (int userId : users) { 17204 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 17205 returnCode = deletePackageX(internalPackageName, versionCode, 17206 userId, userFlags); 17207 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 17208 Slog.w(TAG, "Package delete failed for user " + userId 17209 + ", returnCode " + returnCode); 17210 } 17211 } 17212 } 17213 // The app has only been marked uninstalled for certain users. 17214 // We still need to report that delete was blocked 17215 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 17216 } 17217 } 17218 try { 17219 observer.onPackageDeleted(packageName, returnCode, null); 17220 } catch (RemoteException e) { 17221 Log.i(TAG, "Observer no longer exists."); 17222 } //end catch 17223 } //end run 17224 }); 17225 } 17226 17227 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) { 17228 if (pkg.staticSharedLibName != null) { 17229 return pkg.manifestPackageName; 17230 } 17231 return pkg.packageName; 17232 } 17233 17234 private String resolveInternalPackageNameLPr(String packageName, int versionCode) { 17235 // Handle renamed packages 17236 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName); 17237 packageName = normalizedPackageName != null ? normalizedPackageName : packageName; 17238 17239 // Is this a static library? 17240 SparseArray<SharedLibraryEntry> versionedLib = 17241 mStaticLibsByDeclaringPackage.get(packageName); 17242 if (versionedLib == null || versionedLib.size() <= 0) { 17243 return packageName; 17244 } 17245 17246 // Figure out which lib versions the caller can see 17247 SparseIntArray versionsCallerCanSee = null; 17248 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); 17249 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID 17250 && callingAppId != Process.ROOT_UID) { 17251 versionsCallerCanSee = new SparseIntArray(); 17252 String libName = versionedLib.valueAt(0).info.getName(); 17253 String[] uidPackages = getPackagesForUid(Binder.getCallingUid()); 17254 if (uidPackages != null) { 17255 for (String uidPackage : uidPackages) { 17256 PackageSetting ps = mSettings.getPackageLPr(uidPackage); 17257 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName); 17258 if (libIdx >= 0) { 17259 final int libVersion = ps.usesStaticLibrariesVersions[libIdx]; 17260 versionsCallerCanSee.append(libVersion, libVersion); 17261 } 17262 } 17263 } 17264 } 17265 17266 // Caller can see nothing - done 17267 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) { 17268 return packageName; 17269 } 17270 17271 // Find the version the caller can see and the app version code 17272 SharedLibraryEntry highestVersion = null; 17273 final int versionCount = versionedLib.size(); 17274 for (int i = 0; i < versionCount; i++) { 17275 SharedLibraryEntry libEntry = versionedLib.valueAt(i); 17276 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey( 17277 libEntry.info.getVersion()) < 0) { 17278 continue; 17279 } 17280 // TODO: We will change version code to long, so in the new API it is long 17281 final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode(); 17282 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) { 17283 if (libVersionCode == versionCode) { 17284 return libEntry.apk; 17285 } 17286 } else if (highestVersion == null) { 17287 highestVersion = libEntry; 17288 } else if (libVersionCode > highestVersion.info 17289 .getDeclaringPackage().getVersionCode()) { 17290 highestVersion = libEntry; 17291 } 17292 } 17293 17294 if (highestVersion != null) { 17295 return highestVersion.apk; 17296 } 17297 17298 return packageName; 17299 } 17300 17301 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) { 17302 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID 17303 || callingUid == Process.SYSTEM_UID) { 17304 return true; 17305 } 17306 final int callingUserId = UserHandle.getUserId(callingUid); 17307 // If the caller installed the pkgName, then allow it to silently uninstall. 17308 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) { 17309 return true; 17310 } 17311 17312 // Allow package verifier to silently uninstall. 17313 if (mRequiredVerifierPackage != null && 17314 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) { 17315 return true; 17316 } 17317 17318 // Allow package uninstaller to silently uninstall. 17319 if (mRequiredUninstallerPackage != null && 17320 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { 17321 return true; 17322 } 17323 17324 // Allow storage manager to silently uninstall. 17325 if (mStorageManagerPackage != null && 17326 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { 17327 return true; 17328 } 17329 return false; 17330 } 17331 17332 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 17333 int[] result = EMPTY_INT_ARRAY; 17334 for (int userId : userIds) { 17335 if (getBlockUninstallForUser(packageName, userId)) { 17336 result = ArrayUtils.appendInt(result, userId); 17337 } 17338 } 17339 return result; 17340 } 17341 17342 @Override 17343 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 17344 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 17345 } 17346 17347 private boolean isPackageDeviceAdmin(String packageName, int userId) { 17348 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 17349 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 17350 try { 17351 if (dpm != null) { 17352 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 17353 /* callingUserOnly =*/ false); 17354 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 17355 : deviceOwnerComponentName.getPackageName(); 17356 // Does the package contains the device owner? 17357 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 17358 // this check is probably not needed, since DO should be registered as a device 17359 // admin on some user too. (Original bug for this: b/17657954) 17360 if (packageName.equals(deviceOwnerPackageName)) { 17361 return true; 17362 } 17363 // Does it contain a device admin for any user? 17364 int[] users; 17365 if (userId == UserHandle.USER_ALL) { 17366 users = sUserManager.getUserIds(); 17367 } else { 17368 users = new int[]{userId}; 17369 } 17370 for (int i = 0; i < users.length; ++i) { 17371 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 17372 return true; 17373 } 17374 } 17375 } 17376 } catch (RemoteException e) { 17377 } 17378 return false; 17379 } 17380 17381 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 17382 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 17383 } 17384 17385 /** 17386 * This method is an internal method that could be get invoked either 17387 * to delete an installed package or to clean up a failed installation. 17388 * After deleting an installed package, a broadcast is sent to notify any 17389 * listeners that the package has been removed. For cleaning up a failed 17390 * installation, the broadcast is not necessary since the package's 17391 * installation wouldn't have sent the initial broadcast either 17392 * The key steps in deleting a package are 17393 * deleting the package information in internal structures like mPackages, 17394 * deleting the packages base directories through installd 17395 * updating mSettings to reflect current status 17396 * persisting settings for later use 17397 * sending a broadcast if necessary 17398 */ 17399 private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) { 17400 final PackageRemovedInfo info = new PackageRemovedInfo(); 17401 final boolean res; 17402 17403 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 17404 ? UserHandle.USER_ALL : userId; 17405 17406 if (isPackageDeviceAdmin(packageName, removeUser)) { 17407 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 17408 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 17409 } 17410 17411 PackageSetting uninstalledPs = null; 17412 PackageParser.Package pkg = null; 17413 17414 // for the uninstall-updates case and restricted profiles, remember the per- 17415 // user handle installed state 17416 int[] allUsers; 17417 synchronized (mPackages) { 17418 uninstalledPs = mSettings.mPackages.get(packageName); 17419 if (uninstalledPs == null) { 17420 Slog.w(TAG, "Not removing non-existent package " + packageName); 17421 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17422 } 17423 17424 if (versionCode != PackageManager.VERSION_CODE_HIGHEST 17425 && uninstalledPs.versionCode != versionCode) { 17426 Slog.w(TAG, "Not removing package " + packageName + " with versionCode " 17427 + uninstalledPs.versionCode + " != " + versionCode); 17428 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17429 } 17430 17431 // Static shared libs can be declared by any package, so let us not 17432 // allow removing a package if it provides a lib others depend on. 17433 pkg = mPackages.get(packageName); 17434 if (pkg != null && pkg.staticSharedLibName != null) { 17435 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName, 17436 pkg.staticSharedLibVersion); 17437 if (libEntry != null) { 17438 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr( 17439 libEntry.info, 0, userId); 17440 if (!ArrayUtils.isEmpty(libClientPackages)) { 17441 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName 17442 + " hosting lib " + libEntry.info.getName() + " version " 17443 + libEntry.info.getVersion() + " used by " + libClientPackages); 17444 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY; 17445 } 17446 } 17447 } 17448 17449 allUsers = sUserManager.getUserIds(); 17450 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 17451 } 17452 17453 final int freezeUser; 17454 if (isUpdatedSystemApp(uninstalledPs) 17455 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 17456 // We're downgrading a system app, which will apply to all users, so 17457 // freeze them all during the downgrade 17458 freezeUser = UserHandle.USER_ALL; 17459 } else { 17460 freezeUser = removeUser; 17461 } 17462 17463 synchronized (mInstallLock) { 17464 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 17465 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 17466 deleteFlags, "deletePackageX")) { 17467 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 17468 deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null); 17469 } 17470 synchronized (mPackages) { 17471 if (res) { 17472 if (pkg != null) { 17473 mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers); 17474 } 17475 updateSequenceNumberLP(packageName, info.removedUsers); 17476 } 17477 } 17478 } 17479 17480 if (res) { 17481 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 17482 info.sendPackageRemovedBroadcasts(killApp); 17483 info.sendSystemPackageUpdatedBroadcasts(); 17484 info.sendSystemPackageAppearedBroadcasts(); 17485 } 17486 // Force a gc here. 17487 Runtime.getRuntime().gc(); 17488 // Delete the resources here after sending the broadcast to let 17489 // other processes clean up before deleting resources. 17490 if (info.args != null) { 17491 synchronized (mInstallLock) { 17492 info.args.doPostDeleteLI(true); 17493 } 17494 } 17495 17496 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17497 } 17498 17499 class PackageRemovedInfo { 17500 String removedPackage; 17501 int uid = -1; 17502 int removedAppId = -1; 17503 int[] origUsers; 17504 int[] removedUsers = null; 17505 SparseArray<Integer> installReasons; 17506 boolean isRemovedPackageSystemUpdate = false; 17507 boolean isUpdate; 17508 boolean dataRemoved; 17509 boolean removedForAllUsers; 17510 boolean isStaticSharedLib; 17511 // Clean up resources deleted packages. 17512 InstallArgs args = null; 17513 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 17514 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 17515 17516 void sendPackageRemovedBroadcasts(boolean killApp) { 17517 sendPackageRemovedBroadcastInternal(killApp); 17518 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 17519 for (int i = 0; i < childCount; i++) { 17520 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 17521 childInfo.sendPackageRemovedBroadcastInternal(killApp); 17522 } 17523 } 17524 17525 void sendSystemPackageUpdatedBroadcasts() { 17526 if (isRemovedPackageSystemUpdate) { 17527 sendSystemPackageUpdatedBroadcastsInternal(); 17528 final int childCount = (removedChildPackages != null) 17529 ? removedChildPackages.size() : 0; 17530 for (int i = 0; i < childCount; i++) { 17531 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 17532 if (childInfo.isRemovedPackageSystemUpdate) { 17533 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 17534 } 17535 } 17536 } 17537 } 17538 17539 void sendSystemPackageAppearedBroadcasts() { 17540 final int packageCount = (appearedChildPackages != null) 17541 ? appearedChildPackages.size() : 0; 17542 for (int i = 0; i < packageCount; i++) { 17543 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 17544 sendPackageAddedForNewUsers(installedInfo.name, true, 17545 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers); 17546 } 17547 } 17548 17549 private void sendSystemPackageUpdatedBroadcastsInternal() { 17550 Bundle extras = new Bundle(2); 17551 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 17552 extras.putBoolean(Intent.EXTRA_REPLACING, true); 17553 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 17554 extras, 0, null, null, null); 17555 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 17556 extras, 0, null, null, null); 17557 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 17558 null, 0, removedPackage, null, null); 17559 } 17560 17561 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 17562 // Don't send static shared library removal broadcasts as these 17563 // libs are visible only the the apps that depend on them an one 17564 // cannot remove the library if it has a dependency. 17565 if (isStaticSharedLib) { 17566 return; 17567 } 17568 Bundle extras = new Bundle(2); 17569 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 17570 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 17571 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 17572 if (isUpdate || isRemovedPackageSystemUpdate) { 17573 extras.putBoolean(Intent.EXTRA_REPLACING, true); 17574 } 17575 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 17576 if (removedPackage != null) { 17577 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 17578 extras, 0, null, null, removedUsers); 17579 if (dataRemoved && !isRemovedPackageSystemUpdate) { 17580 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 17581 removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, 17582 null, null, removedUsers); 17583 } 17584 } 17585 if (removedAppId >= 0) { 17586 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 17587 removedUsers); 17588 } 17589 } 17590 } 17591 17592 /* 17593 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 17594 * flag is not set, the data directory is removed as well. 17595 * make sure this flag is set for partially installed apps. If not its meaningless to 17596 * delete a partially installed application. 17597 */ 17598 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 17599 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 17600 String packageName = ps.name; 17601 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 17602 // Retrieve object to delete permissions for shared user later on 17603 final PackageParser.Package deletedPkg; 17604 final PackageSetting deletedPs; 17605 // reader 17606 synchronized (mPackages) { 17607 deletedPkg = mPackages.get(packageName); 17608 deletedPs = mSettings.mPackages.get(packageName); 17609 if (outInfo != null) { 17610 outInfo.removedPackage = packageName; 17611 outInfo.isStaticSharedLib = deletedPkg != null 17612 && deletedPkg.staticSharedLibName != null; 17613 outInfo.removedUsers = deletedPs != null 17614 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 17615 : null; 17616 } 17617 } 17618 17619 removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0); 17620 17621 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 17622 final PackageParser.Package resolvedPkg; 17623 if (deletedPkg != null) { 17624 resolvedPkg = deletedPkg; 17625 } else { 17626 // We don't have a parsed package when it lives on an ejected 17627 // adopted storage device, so fake something together 17628 resolvedPkg = new PackageParser.Package(ps.name); 17629 resolvedPkg.setVolumeUuid(ps.volumeUuid); 17630 } 17631 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 17632 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 17633 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 17634 if (outInfo != null) { 17635 outInfo.dataRemoved = true; 17636 } 17637 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 17638 } 17639 17640 int removedAppId = -1; 17641 17642 // writer 17643 synchronized (mPackages) { 17644 boolean installedStateChanged = false; 17645 if (deletedPs != null) { 17646 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 17647 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 17648 clearDefaultBrowserIfNeeded(packageName); 17649 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 17650 removedAppId = mSettings.removePackageLPw(packageName); 17651 if (outInfo != null) { 17652 outInfo.removedAppId = removedAppId; 17653 } 17654 updatePermissionsLPw(deletedPs.name, null, 0); 17655 if (deletedPs.sharedUser != null) { 17656 // Remove permissions associated with package. Since runtime 17657 // permissions are per user we have to kill the removed package 17658 // or packages running under the shared user of the removed 17659 // package if revoking the permissions requested only by the removed 17660 // package is successful and this causes a change in gids. 17661 for (int userId : UserManagerService.getInstance().getUserIds()) { 17662 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 17663 userId); 17664 if (userIdToKill == UserHandle.USER_ALL 17665 || userIdToKill >= UserHandle.USER_SYSTEM) { 17666 // If gids changed for this user, kill all affected packages. 17667 mHandler.post(new Runnable() { 17668 @Override 17669 public void run() { 17670 // This has to happen with no lock held. 17671 killApplication(deletedPs.name, deletedPs.appId, 17672 KILL_APP_REASON_GIDS_CHANGED); 17673 } 17674 }); 17675 break; 17676 } 17677 } 17678 } 17679 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 17680 } 17681 // make sure to preserve per-user disabled state if this removal was just 17682 // a downgrade of a system app to the factory package 17683 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 17684 if (DEBUG_REMOVE) { 17685 Slog.d(TAG, "Propagating install state across downgrade"); 17686 } 17687 for (int userId : allUserHandles) { 17688 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 17689 if (DEBUG_REMOVE) { 17690 Slog.d(TAG, " user " + userId + " => " + installed); 17691 } 17692 if (installed != ps.getInstalled(userId)) { 17693 installedStateChanged = true; 17694 } 17695 ps.setInstalled(installed, userId); 17696 } 17697 } 17698 } 17699 // can downgrade to reader 17700 if (writeSettings) { 17701 // Save settings now 17702 mSettings.writeLPr(); 17703 } 17704 if (installedStateChanged) { 17705 mSettings.writeKernelMappingLPr(ps); 17706 } 17707 } 17708 if (removedAppId != -1) { 17709 // A user ID was deleted here. Go through all users and remove it 17710 // from KeyStore. 17711 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId); 17712 } 17713 } 17714 17715 static boolean locationIsPrivileged(File path) { 17716 try { 17717 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 17718 .getCanonicalPath(); 17719 return path.getCanonicalPath().startsWith(privilegedAppDir); 17720 } catch (IOException e) { 17721 Slog.e(TAG, "Unable to access code path " + path); 17722 } 17723 return false; 17724 } 17725 17726 /* 17727 * Tries to delete system package. 17728 */ 17729 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 17730 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 17731 boolean writeSettings) { 17732 if (deletedPs.parentPackageName != null) { 17733 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 17734 return false; 17735 } 17736 17737 final boolean applyUserRestrictions 17738 = (allUserHandles != null) && (outInfo.origUsers != null); 17739 final PackageSetting disabledPs; 17740 // Confirm if the system package has been updated 17741 // An updated system app can be deleted. This will also have to restore 17742 // the system pkg from system partition 17743 // reader 17744 synchronized (mPackages) { 17745 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 17746 } 17747 17748 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 17749 + " disabledPs=" + disabledPs); 17750 17751 if (disabledPs == null) { 17752 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 17753 return false; 17754 } else if (DEBUG_REMOVE) { 17755 Slog.d(TAG, "Deleting system pkg from data partition"); 17756 } 17757 17758 if (DEBUG_REMOVE) { 17759 if (applyUserRestrictions) { 17760 Slog.d(TAG, "Remembering install states:"); 17761 for (int userId : allUserHandles) { 17762 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 17763 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 17764 } 17765 } 17766 } 17767 17768 // Delete the updated package 17769 outInfo.isRemovedPackageSystemUpdate = true; 17770 if (outInfo.removedChildPackages != null) { 17771 final int childCount = (deletedPs.childPackageNames != null) 17772 ? deletedPs.childPackageNames.size() : 0; 17773 for (int i = 0; i < childCount; i++) { 17774 String childPackageName = deletedPs.childPackageNames.get(i); 17775 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 17776 .contains(childPackageName)) { 17777 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 17778 childPackageName); 17779 if (childInfo != null) { 17780 childInfo.isRemovedPackageSystemUpdate = true; 17781 } 17782 } 17783 } 17784 } 17785 17786 if (disabledPs.versionCode < deletedPs.versionCode) { 17787 // Delete data for downgrades 17788 flags &= ~PackageManager.DELETE_KEEP_DATA; 17789 } else { 17790 // Preserve data by setting flag 17791 flags |= PackageManager.DELETE_KEEP_DATA; 17792 } 17793 17794 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 17795 outInfo, writeSettings, disabledPs.pkg); 17796 if (!ret) { 17797 return false; 17798 } 17799 17800 // writer 17801 synchronized (mPackages) { 17802 // Reinstate the old system package 17803 enableSystemPackageLPw(disabledPs.pkg); 17804 // Remove any native libraries from the upgraded package. 17805 removeNativeBinariesLI(deletedPs); 17806 } 17807 17808 // Install the system package 17809 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 17810 int parseFlags = mDefParseFlags 17811 | PackageParser.PARSE_MUST_BE_APK 17812 | PackageParser.PARSE_IS_SYSTEM 17813 | PackageParser.PARSE_IS_SYSTEM_DIR; 17814 if (locationIsPrivileged(disabledPs.codePath)) { 17815 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 17816 } 17817 17818 final PackageParser.Package newPkg; 17819 try { 17820 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */, 17821 0 /* currentTime */, null); 17822 } catch (PackageManagerException e) { 17823 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 17824 + e.getMessage()); 17825 return false; 17826 } 17827 17828 try { 17829 // update shared libraries for the newly re-installed system package 17830 updateSharedLibrariesLPr(newPkg, null); 17831 } catch (PackageManagerException e) { 17832 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 17833 } 17834 17835 prepareAppDataAfterInstallLIF(newPkg); 17836 17837 // writer 17838 synchronized (mPackages) { 17839 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 17840 17841 // Propagate the permissions state as we do not want to drop on the floor 17842 // runtime permissions. The update permissions method below will take 17843 // care of removing obsolete permissions and grant install permissions. 17844 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 17845 updatePermissionsLPw(newPkg.packageName, newPkg, 17846 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 17847 17848 if (applyUserRestrictions) { 17849 boolean installedStateChanged = false; 17850 if (DEBUG_REMOVE) { 17851 Slog.d(TAG, "Propagating install state across reinstall"); 17852 } 17853 for (int userId : allUserHandles) { 17854 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 17855 if (DEBUG_REMOVE) { 17856 Slog.d(TAG, " user " + userId + " => " + installed); 17857 } 17858 if (installed != ps.getInstalled(userId)) { 17859 installedStateChanged = true; 17860 } 17861 ps.setInstalled(installed, userId); 17862 17863 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17864 } 17865 // Regardless of writeSettings we need to ensure that this restriction 17866 // state propagation is persisted 17867 mSettings.writeAllUsersPackageRestrictionsLPr(); 17868 if (installedStateChanged) { 17869 mSettings.writeKernelMappingLPr(ps); 17870 } 17871 } 17872 // can downgrade to reader here 17873 if (writeSettings) { 17874 mSettings.writeLPr(); 17875 } 17876 } 17877 return true; 17878 } 17879 17880 private boolean deleteInstalledPackageLIF(PackageSetting ps, 17881 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 17882 PackageRemovedInfo outInfo, boolean writeSettings, 17883 PackageParser.Package replacingPackage) { 17884 synchronized (mPackages) { 17885 if (outInfo != null) { 17886 outInfo.uid = ps.appId; 17887 } 17888 17889 if (outInfo != null && outInfo.removedChildPackages != null) { 17890 final int childCount = (ps.childPackageNames != null) 17891 ? ps.childPackageNames.size() : 0; 17892 for (int i = 0; i < childCount; i++) { 17893 String childPackageName = ps.childPackageNames.get(i); 17894 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 17895 if (childPs == null) { 17896 return false; 17897 } 17898 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 17899 childPackageName); 17900 if (childInfo != null) { 17901 childInfo.uid = childPs.appId; 17902 } 17903 } 17904 } 17905 } 17906 17907 // Delete package data from internal structures and also remove data if flag is set 17908 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 17909 17910 // Delete the child packages data 17911 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 17912 for (int i = 0; i < childCount; i++) { 17913 PackageSetting childPs; 17914 synchronized (mPackages) { 17915 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 17916 } 17917 if (childPs != null) { 17918 PackageRemovedInfo childOutInfo = (outInfo != null 17919 && outInfo.removedChildPackages != null) 17920 ? outInfo.removedChildPackages.get(childPs.name) : null; 17921 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 17922 && (replacingPackage != null 17923 && !replacingPackage.hasChildPackage(childPs.name)) 17924 ? flags & ~DELETE_KEEP_DATA : flags; 17925 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 17926 deleteFlags, writeSettings); 17927 } 17928 } 17929 17930 // Delete application code and resources only for parent packages 17931 if (ps.parentPackageName == null) { 17932 if (deleteCodeAndResources && (outInfo != null)) { 17933 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 17934 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 17935 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 17936 } 17937 } 17938 17939 return true; 17940 } 17941 17942 @Override 17943 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 17944 int userId) { 17945 mContext.enforceCallingOrSelfPermission( 17946 android.Manifest.permission.DELETE_PACKAGES, null); 17947 synchronized (mPackages) { 17948 PackageSetting ps = mSettings.mPackages.get(packageName); 17949 if (ps == null) { 17950 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 17951 return false; 17952 } 17953 // Cannot block uninstall of static shared libs as they are 17954 // considered a part of the using app (emulating static linking). 17955 // Also static libs are installed always on internal storage. 17956 PackageParser.Package pkg = mPackages.get(packageName); 17957 if (pkg != null && pkg.staticSharedLibName != null) { 17958 Slog.w(TAG, "Cannot block uninstall of package: " + packageName 17959 + " providing static shared library: " + pkg.staticSharedLibName); 17960 return false; 17961 } 17962 if (!ps.getInstalled(userId)) { 17963 // Can't block uninstall for an app that is not installed or enabled. 17964 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 17965 return false; 17966 } 17967 ps.setBlockUninstall(blockUninstall, userId); 17968 mSettings.writePackageRestrictionsLPr(userId); 17969 } 17970 return true; 17971 } 17972 17973 @Override 17974 public boolean getBlockUninstallForUser(String packageName, int userId) { 17975 synchronized (mPackages) { 17976 PackageSetting ps = mSettings.mPackages.get(packageName); 17977 if (ps == null) { 17978 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 17979 return false; 17980 } 17981 return ps.getBlockUninstall(userId); 17982 } 17983 } 17984 17985 @Override 17986 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 17987 int callingUid = Binder.getCallingUid(); 17988 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 17989 throw new SecurityException( 17990 "setRequiredForSystemUser can only be run by the system or root"); 17991 } 17992 synchronized (mPackages) { 17993 PackageSetting ps = mSettings.mPackages.get(packageName); 17994 if (ps == null) { 17995 Log.w(TAG, "Package doesn't exist: " + packageName); 17996 return false; 17997 } 17998 if (systemUserApp) { 17999 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 18000 } else { 18001 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 18002 } 18003 mSettings.writeLPr(); 18004 } 18005 return true; 18006 } 18007 18008 /* 18009 * This method handles package deletion in general 18010 */ 18011 private boolean deletePackageLIF(String packageName, UserHandle user, 18012 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 18013 PackageRemovedInfo outInfo, boolean writeSettings, 18014 PackageParser.Package replacingPackage) { 18015 if (packageName == null) { 18016 Slog.w(TAG, "Attempt to delete null packageName."); 18017 return false; 18018 } 18019 18020 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 18021 18022 PackageSetting ps; 18023 synchronized (mPackages) { 18024 ps = mSettings.mPackages.get(packageName); 18025 if (ps == null) { 18026 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 18027 return false; 18028 } 18029 18030 if (ps.parentPackageName != null && (!isSystemApp(ps) 18031 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 18032 if (DEBUG_REMOVE) { 18033 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 18034 + ((user == null) ? UserHandle.USER_ALL : user)); 18035 } 18036 final int removedUserId = (user != null) ? user.getIdentifier() 18037 : UserHandle.USER_ALL; 18038 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 18039 return false; 18040 } 18041 markPackageUninstalledForUserLPw(ps, user); 18042 scheduleWritePackageRestrictionsLocked(user); 18043 return true; 18044 } 18045 } 18046 18047 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 18048 && user.getIdentifier() != UserHandle.USER_ALL)) { 18049 // The caller is asking that the package only be deleted for a single 18050 // user. To do this, we just mark its uninstalled state and delete 18051 // its data. If this is a system app, we only allow this to happen if 18052 // they have set the special DELETE_SYSTEM_APP which requests different 18053 // semantics than normal for uninstalling system apps. 18054 markPackageUninstalledForUserLPw(ps, user); 18055 18056 if (!isSystemApp(ps)) { 18057 // Do not uninstall the APK if an app should be cached 18058 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 18059 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 18060 // Other user still have this package installed, so all 18061 // we need to do is clear this user's data and save that 18062 // it is uninstalled. 18063 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 18064 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 18065 return false; 18066 } 18067 scheduleWritePackageRestrictionsLocked(user); 18068 return true; 18069 } else { 18070 // We need to set it back to 'installed' so the uninstall 18071 // broadcasts will be sent correctly. 18072 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 18073 ps.setInstalled(true, user.getIdentifier()); 18074 mSettings.writeKernelMappingLPr(ps); 18075 } 18076 } else { 18077 // This is a system app, so we assume that the 18078 // other users still have this package installed, so all 18079 // we need to do is clear this user's data and save that 18080 // it is uninstalled. 18081 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 18082 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 18083 return false; 18084 } 18085 scheduleWritePackageRestrictionsLocked(user); 18086 return true; 18087 } 18088 } 18089 18090 // If we are deleting a composite package for all users, keep track 18091 // of result for each child. 18092 if (ps.childPackageNames != null && outInfo != null) { 18093 synchronized (mPackages) { 18094 final int childCount = ps.childPackageNames.size(); 18095 outInfo.removedChildPackages = new ArrayMap<>(childCount); 18096 for (int i = 0; i < childCount; i++) { 18097 String childPackageName = ps.childPackageNames.get(i); 18098 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 18099 childInfo.removedPackage = childPackageName; 18100 outInfo.removedChildPackages.put(childPackageName, childInfo); 18101 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 18102 if (childPs != null) { 18103 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 18104 } 18105 } 18106 } 18107 } 18108 18109 boolean ret = false; 18110 if (isSystemApp(ps)) { 18111 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 18112 // When an updated system application is deleted we delete the existing resources 18113 // as well and fall back to existing code in system partition 18114 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 18115 } else { 18116 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 18117 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 18118 outInfo, writeSettings, replacingPackage); 18119 } 18120 18121 // Take a note whether we deleted the package for all users 18122 if (outInfo != null) { 18123 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 18124 if (outInfo.removedChildPackages != null) { 18125 synchronized (mPackages) { 18126 final int childCount = outInfo.removedChildPackages.size(); 18127 for (int i = 0; i < childCount; i++) { 18128 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 18129 if (childInfo != null) { 18130 childInfo.removedForAllUsers = mPackages.get( 18131 childInfo.removedPackage) == null; 18132 } 18133 } 18134 } 18135 } 18136 // If we uninstalled an update to a system app there may be some 18137 // child packages that appeared as they are declared in the system 18138 // app but were not declared in the update. 18139 if (isSystemApp(ps)) { 18140 synchronized (mPackages) { 18141 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name); 18142 final int childCount = (updatedPs.childPackageNames != null) 18143 ? updatedPs.childPackageNames.size() : 0; 18144 for (int i = 0; i < childCount; i++) { 18145 String childPackageName = updatedPs.childPackageNames.get(i); 18146 if (outInfo.removedChildPackages == null 18147 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 18148 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 18149 if (childPs == null) { 18150 continue; 18151 } 18152 PackageInstalledInfo installRes = new PackageInstalledInfo(); 18153 installRes.name = childPackageName; 18154 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 18155 installRes.pkg = mPackages.get(childPackageName); 18156 installRes.uid = childPs.pkg.applicationInfo.uid; 18157 if (outInfo.appearedChildPackages == null) { 18158 outInfo.appearedChildPackages = new ArrayMap<>(); 18159 } 18160 outInfo.appearedChildPackages.put(childPackageName, installRes); 18161 } 18162 } 18163 } 18164 } 18165 } 18166 18167 return ret; 18168 } 18169 18170 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 18171 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 18172 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 18173 for (int nextUserId : userIds) { 18174 if (DEBUG_REMOVE) { 18175 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 18176 } 18177 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 18178 false /*installed*/, 18179 true /*stopped*/, 18180 true /*notLaunched*/, 18181 false /*hidden*/, 18182 false /*suspended*/, 18183 false /*instantApp*/, 18184 null /*lastDisableAppCaller*/, 18185 null /*enabledComponents*/, 18186 null /*disabledComponents*/, 18187 false /*blockUninstall*/, 18188 ps.readUserState(nextUserId).domainVerificationStatus, 18189 0, PackageManager.INSTALL_REASON_UNKNOWN); 18190 } 18191 mSettings.writeKernelMappingLPr(ps); 18192 } 18193 18194 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 18195 PackageRemovedInfo outInfo) { 18196 final PackageParser.Package pkg; 18197 synchronized (mPackages) { 18198 pkg = mPackages.get(ps.name); 18199 } 18200 18201 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 18202 : new int[] {userId}; 18203 for (int nextUserId : userIds) { 18204 if (DEBUG_REMOVE) { 18205 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 18206 + nextUserId); 18207 } 18208 18209 destroyAppDataLIF(pkg, userId, 18210 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 18211 destroyAppProfilesLIF(pkg, userId); 18212 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 18213 schedulePackageCleaning(ps.name, nextUserId, false); 18214 synchronized (mPackages) { 18215 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 18216 scheduleWritePackageRestrictionsLocked(nextUserId); 18217 } 18218 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 18219 } 18220 } 18221 18222 if (outInfo != null) { 18223 outInfo.removedPackage = ps.name; 18224 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null; 18225 outInfo.removedAppId = ps.appId; 18226 outInfo.removedUsers = userIds; 18227 } 18228 18229 return true; 18230 } 18231 18232 private final class ClearStorageConnection implements ServiceConnection { 18233 IMediaContainerService mContainerService; 18234 18235 @Override 18236 public void onServiceConnected(ComponentName name, IBinder service) { 18237 synchronized (this) { 18238 mContainerService = IMediaContainerService.Stub 18239 .asInterface(Binder.allowBlocking(service)); 18240 notifyAll(); 18241 } 18242 } 18243 18244 @Override 18245 public void onServiceDisconnected(ComponentName name) { 18246 } 18247 } 18248 18249 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 18250 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 18251 18252 final boolean mounted; 18253 if (Environment.isExternalStorageEmulated()) { 18254 mounted = true; 18255 } else { 18256 final String status = Environment.getExternalStorageState(); 18257 18258 mounted = status.equals(Environment.MEDIA_MOUNTED) 18259 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 18260 } 18261 18262 if (!mounted) { 18263 return; 18264 } 18265 18266 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 18267 int[] users; 18268 if (userId == UserHandle.USER_ALL) { 18269 users = sUserManager.getUserIds(); 18270 } else { 18271 users = new int[] { userId }; 18272 } 18273 final ClearStorageConnection conn = new ClearStorageConnection(); 18274 if (mContext.bindServiceAsUser( 18275 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 18276 try { 18277 for (int curUser : users) { 18278 long timeout = SystemClock.uptimeMillis() + 5000; 18279 synchronized (conn) { 18280 long now; 18281 while (conn.mContainerService == null && 18282 (now = SystemClock.uptimeMillis()) < timeout) { 18283 try { 18284 conn.wait(timeout - now); 18285 } catch (InterruptedException e) { 18286 } 18287 } 18288 } 18289 if (conn.mContainerService == null) { 18290 return; 18291 } 18292 18293 final UserEnvironment userEnv = new UserEnvironment(curUser); 18294 clearDirectory(conn.mContainerService, 18295 userEnv.buildExternalStorageAppCacheDirs(packageName)); 18296 if (allData) { 18297 clearDirectory(conn.mContainerService, 18298 userEnv.buildExternalStorageAppDataDirs(packageName)); 18299 clearDirectory(conn.mContainerService, 18300 userEnv.buildExternalStorageAppMediaDirs(packageName)); 18301 } 18302 } 18303 } finally { 18304 mContext.unbindService(conn); 18305 } 18306 } 18307 } 18308 18309 @Override 18310 public void clearApplicationProfileData(String packageName) { 18311 enforceSystemOrRoot("Only the system can clear all profile data"); 18312 18313 final PackageParser.Package pkg; 18314 synchronized (mPackages) { 18315 pkg = mPackages.get(packageName); 18316 } 18317 18318 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 18319 synchronized (mInstallLock) { 18320 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 18321 } 18322 } 18323 } 18324 18325 @Override 18326 public void clearApplicationUserData(final String packageName, 18327 final IPackageDataObserver observer, final int userId) { 18328 mContext.enforceCallingOrSelfPermission( 18329 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 18330 18331 enforceCrossUserPermission(Binder.getCallingUid(), userId, 18332 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 18333 18334 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 18335 throw new SecurityException("Cannot clear data for a protected package: " 18336 + packageName); 18337 } 18338 // Queue up an async operation since the package deletion may take a little while. 18339 mHandler.post(new Runnable() { 18340 public void run() { 18341 mHandler.removeCallbacks(this); 18342 final boolean succeeded; 18343 try (PackageFreezer freezer = freezePackage(packageName, 18344 "clearApplicationUserData")) { 18345 synchronized (mInstallLock) { 18346 succeeded = clearApplicationUserDataLIF(packageName, userId); 18347 } 18348 clearExternalStorageDataSync(packageName, userId, true); 18349 synchronized (mPackages) { 18350 mInstantAppRegistry.deleteInstantApplicationMetadataLPw( 18351 packageName, userId); 18352 } 18353 } 18354 if (succeeded) { 18355 // invoke DeviceStorageMonitor's update method to clear any notifications 18356 DeviceStorageMonitorInternal dsm = LocalServices 18357 .getService(DeviceStorageMonitorInternal.class); 18358 if (dsm != null) { 18359 dsm.checkMemory(); 18360 } 18361 } 18362 if(observer != null) { 18363 try { 18364 observer.onRemoveCompleted(packageName, succeeded); 18365 } catch (RemoteException e) { 18366 Log.i(TAG, "Observer no longer exists."); 18367 } 18368 } //end if observer 18369 } //end run 18370 }); 18371 } 18372 18373 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 18374 if (packageName == null) { 18375 Slog.w(TAG, "Attempt to delete null packageName."); 18376 return false; 18377 } 18378 18379 // Try finding details about the requested package 18380 PackageParser.Package pkg; 18381 synchronized (mPackages) { 18382 pkg = mPackages.get(packageName); 18383 if (pkg == null) { 18384 final PackageSetting ps = mSettings.mPackages.get(packageName); 18385 if (ps != null) { 18386 pkg = ps.pkg; 18387 } 18388 } 18389 18390 if (pkg == null) { 18391 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 18392 return false; 18393 } 18394 18395 PackageSetting ps = (PackageSetting) pkg.mExtras; 18396 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 18397 } 18398 18399 clearAppDataLIF(pkg, userId, 18400 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 18401 18402 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18403 removeKeystoreDataIfNeeded(userId, appId); 18404 18405 UserManagerInternal umInternal = getUserManagerInternal(); 18406 final int flags; 18407 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 18408 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18409 } else if (umInternal.isUserRunning(userId)) { 18410 flags = StorageManager.FLAG_STORAGE_DE; 18411 } else { 18412 flags = 0; 18413 } 18414 prepareAppDataContentsLIF(pkg, userId, flags); 18415 18416 return true; 18417 } 18418 18419 /** 18420 * Reverts user permission state changes (permissions and flags) in 18421 * all packages for a given user. 18422 * 18423 * @param userId The device user for which to do a reset. 18424 */ 18425 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 18426 final int packageCount = mPackages.size(); 18427 for (int i = 0; i < packageCount; i++) { 18428 PackageParser.Package pkg = mPackages.valueAt(i); 18429 PackageSetting ps = (PackageSetting) pkg.mExtras; 18430 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 18431 } 18432 } 18433 18434 private void resetNetworkPolicies(int userId) { 18435 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 18436 } 18437 18438 /** 18439 * Reverts user permission state changes (permissions and flags). 18440 * 18441 * @param ps The package for which to reset. 18442 * @param userId The device user for which to do a reset. 18443 */ 18444 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 18445 final PackageSetting ps, final int userId) { 18446 if (ps.pkg == null) { 18447 return; 18448 } 18449 18450 // These are flags that can change base on user actions. 18451 final int userSettableMask = FLAG_PERMISSION_USER_SET 18452 | FLAG_PERMISSION_USER_FIXED 18453 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 18454 | FLAG_PERMISSION_REVIEW_REQUIRED; 18455 18456 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 18457 | FLAG_PERMISSION_POLICY_FIXED; 18458 18459 boolean writeInstallPermissions = false; 18460 boolean writeRuntimePermissions = false; 18461 18462 final int permissionCount = ps.pkg.requestedPermissions.size(); 18463 for (int i = 0; i < permissionCount; i++) { 18464 String permission = ps.pkg.requestedPermissions.get(i); 18465 18466 BasePermission bp = mSettings.mPermissions.get(permission); 18467 if (bp == null) { 18468 continue; 18469 } 18470 18471 // If shared user we just reset the state to which only this app contributed. 18472 if (ps.sharedUser != null) { 18473 boolean used = false; 18474 final int packageCount = ps.sharedUser.packages.size(); 18475 for (int j = 0; j < packageCount; j++) { 18476 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 18477 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 18478 && pkg.pkg.requestedPermissions.contains(permission)) { 18479 used = true; 18480 break; 18481 } 18482 } 18483 if (used) { 18484 continue; 18485 } 18486 } 18487 18488 PermissionsState permissionsState = ps.getPermissionsState(); 18489 18490 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 18491 18492 // Always clear the user settable flags. 18493 final boolean hasInstallState = permissionsState.getInstallPermissionState( 18494 bp.name) != null; 18495 // If permission review is enabled and this is a legacy app, mark the 18496 // permission as requiring a review as this is the initial state. 18497 int flags = 0; 18498 if (mPermissionReviewRequired 18499 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 18500 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 18501 } 18502 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 18503 if (hasInstallState) { 18504 writeInstallPermissions = true; 18505 } else { 18506 writeRuntimePermissions = true; 18507 } 18508 } 18509 18510 // Below is only runtime permission handling. 18511 if (!bp.isRuntime()) { 18512 continue; 18513 } 18514 18515 // Never clobber system or policy. 18516 if ((oldFlags & policyOrSystemFlags) != 0) { 18517 continue; 18518 } 18519 18520 // If this permission was granted by default, make sure it is. 18521 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 18522 if (permissionsState.grantRuntimePermission(bp, userId) 18523 != PERMISSION_OPERATION_FAILURE) { 18524 writeRuntimePermissions = true; 18525 } 18526 // If permission review is enabled the permissions for a legacy apps 18527 // are represented as constantly granted runtime ones, so don't revoke. 18528 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 18529 // Otherwise, reset the permission. 18530 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 18531 switch (revokeResult) { 18532 case PERMISSION_OPERATION_SUCCESS: 18533 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 18534 writeRuntimePermissions = true; 18535 final int appId = ps.appId; 18536 mHandler.post(new Runnable() { 18537 @Override 18538 public void run() { 18539 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 18540 } 18541 }); 18542 } break; 18543 } 18544 } 18545 } 18546 18547 // Synchronously write as we are taking permissions away. 18548 if (writeRuntimePermissions) { 18549 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 18550 } 18551 18552 // Synchronously write as we are taking permissions away. 18553 if (writeInstallPermissions) { 18554 mSettings.writeLPr(); 18555 } 18556 } 18557 18558 /** 18559 * Remove entries from the keystore daemon. Will only remove it if the 18560 * {@code appId} is valid. 18561 */ 18562 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 18563 if (appId < 0) { 18564 return; 18565 } 18566 18567 final KeyStore keyStore = KeyStore.getInstance(); 18568 if (keyStore != null) { 18569 if (userId == UserHandle.USER_ALL) { 18570 for (final int individual : sUserManager.getUserIds()) { 18571 keyStore.clearUid(UserHandle.getUid(individual, appId)); 18572 } 18573 } else { 18574 keyStore.clearUid(UserHandle.getUid(userId, appId)); 18575 } 18576 } else { 18577 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 18578 } 18579 } 18580 18581 @Override 18582 public void deleteApplicationCacheFiles(final String packageName, 18583 final IPackageDataObserver observer) { 18584 final int userId = UserHandle.getCallingUserId(); 18585 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 18586 } 18587 18588 @Override 18589 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 18590 final IPackageDataObserver observer) { 18591 mContext.enforceCallingOrSelfPermission( 18592 android.Manifest.permission.DELETE_CACHE_FILES, null); 18593 enforceCrossUserPermission(Binder.getCallingUid(), userId, 18594 /* requireFullPermission= */ true, /* checkShell= */ false, 18595 "delete application cache files"); 18596 18597 final PackageParser.Package pkg; 18598 synchronized (mPackages) { 18599 pkg = mPackages.get(packageName); 18600 } 18601 18602 // Queue up an async operation since the package deletion may take a little while. 18603 mHandler.post(new Runnable() { 18604 public void run() { 18605 synchronized (mInstallLock) { 18606 final int flags = StorageManager.FLAG_STORAGE_DE 18607 | StorageManager.FLAG_STORAGE_CE; 18608 // We're only clearing cache files, so we don't care if the 18609 // app is unfrozen and still able to run 18610 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 18611 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 18612 } 18613 clearExternalStorageDataSync(packageName, userId, false); 18614 if (observer != null) { 18615 try { 18616 observer.onRemoveCompleted(packageName, true); 18617 } catch (RemoteException e) { 18618 Log.i(TAG, "Observer no longer exists."); 18619 } 18620 } 18621 } 18622 }); 18623 } 18624 18625 @Override 18626 public void getPackageSizeInfo(final String packageName, int userHandle, 18627 final IPackageStatsObserver observer) { 18628 throw new UnsupportedOperationException( 18629 "Shame on you for calling a hidden API. Shame!"); 18630 } 18631 18632 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 18633 final PackageSetting ps; 18634 synchronized (mPackages) { 18635 ps = mSettings.mPackages.get(packageName); 18636 if (ps == null) { 18637 Slog.w(TAG, "Failed to find settings for " + packageName); 18638 return false; 18639 } 18640 } 18641 18642 final String[] packageNames = { packageName }; 18643 final long[] ceDataInodes = { ps.getCeDataInode(userId) }; 18644 final String[] codePaths = { ps.codePathString }; 18645 18646 try { 18647 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0, 18648 ps.appId, ceDataInodes, codePaths, stats); 18649 18650 // For now, ignore code size of packages on system partition 18651 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 18652 stats.codeSize = 0; 18653 } 18654 18655 // External clients expect these to be tracked separately 18656 stats.dataSize -= stats.cacheSize; 18657 18658 } catch (InstallerException e) { 18659 Slog.w(TAG, String.valueOf(e)); 18660 return false; 18661 } 18662 18663 return true; 18664 } 18665 18666 private int getUidTargetSdkVersionLockedLPr(int uid) { 18667 Object obj = mSettings.getUserIdLPr(uid); 18668 if (obj instanceof SharedUserSetting) { 18669 final SharedUserSetting sus = (SharedUserSetting) obj; 18670 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 18671 final Iterator<PackageSetting> it = sus.packages.iterator(); 18672 while (it.hasNext()) { 18673 final PackageSetting ps = it.next(); 18674 if (ps.pkg != null) { 18675 int v = ps.pkg.applicationInfo.targetSdkVersion; 18676 if (v < vers) vers = v; 18677 } 18678 } 18679 return vers; 18680 } else if (obj instanceof PackageSetting) { 18681 final PackageSetting ps = (PackageSetting) obj; 18682 if (ps.pkg != null) { 18683 return ps.pkg.applicationInfo.targetSdkVersion; 18684 } 18685 } 18686 return Build.VERSION_CODES.CUR_DEVELOPMENT; 18687 } 18688 18689 @Override 18690 public void addPreferredActivity(IntentFilter filter, int match, 18691 ComponentName[] set, ComponentName activity, int userId) { 18692 addPreferredActivityInternal(filter, match, set, activity, true, userId, 18693 "Adding preferred"); 18694 } 18695 18696 private void addPreferredActivityInternal(IntentFilter filter, int match, 18697 ComponentName[] set, ComponentName activity, boolean always, int userId, 18698 String opname) { 18699 // writer 18700 int callingUid = Binder.getCallingUid(); 18701 enforceCrossUserPermission(callingUid, userId, 18702 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 18703 if (filter.countActions() == 0) { 18704 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 18705 return; 18706 } 18707 synchronized (mPackages) { 18708 if (mContext.checkCallingOrSelfPermission( 18709 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18710 != PackageManager.PERMISSION_GRANTED) { 18711 if (getUidTargetSdkVersionLockedLPr(callingUid) 18712 < Build.VERSION_CODES.FROYO) { 18713 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 18714 + callingUid); 18715 return; 18716 } 18717 mContext.enforceCallingOrSelfPermission( 18718 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18719 } 18720 18721 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 18722 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 18723 + userId + ":"); 18724 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18725 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 18726 scheduleWritePackageRestrictionsLocked(userId); 18727 postPreferredActivityChangedBroadcast(userId); 18728 } 18729 } 18730 18731 private void postPreferredActivityChangedBroadcast(int userId) { 18732 mHandler.post(() -> { 18733 final IActivityManager am = ActivityManager.getService(); 18734 if (am == null) { 18735 return; 18736 } 18737 18738 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 18739 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18740 try { 18741 am.broadcastIntent(null, intent, null, null, 18742 0, null, null, null, android.app.AppOpsManager.OP_NONE, 18743 null, false, false, userId); 18744 } catch (RemoteException e) { 18745 } 18746 }); 18747 } 18748 18749 @Override 18750 public void replacePreferredActivity(IntentFilter filter, int match, 18751 ComponentName[] set, ComponentName activity, int userId) { 18752 if (filter.countActions() != 1) { 18753 throw new IllegalArgumentException( 18754 "replacePreferredActivity expects filter to have only 1 action."); 18755 } 18756 if (filter.countDataAuthorities() != 0 18757 || filter.countDataPaths() != 0 18758 || filter.countDataSchemes() > 1 18759 || filter.countDataTypes() != 0) { 18760 throw new IllegalArgumentException( 18761 "replacePreferredActivity expects filter to have no data authorities, " + 18762 "paths, or types; and at most one scheme."); 18763 } 18764 18765 final int callingUid = Binder.getCallingUid(); 18766 enforceCrossUserPermission(callingUid, userId, 18767 true /* requireFullPermission */, false /* checkShell */, 18768 "replace preferred activity"); 18769 synchronized (mPackages) { 18770 if (mContext.checkCallingOrSelfPermission( 18771 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18772 != PackageManager.PERMISSION_GRANTED) { 18773 if (getUidTargetSdkVersionLockedLPr(callingUid) 18774 < Build.VERSION_CODES.FROYO) { 18775 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 18776 + Binder.getCallingUid()); 18777 return; 18778 } 18779 mContext.enforceCallingOrSelfPermission( 18780 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18781 } 18782 18783 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 18784 if (pir != null) { 18785 // Get all of the existing entries that exactly match this filter. 18786 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 18787 if (existing != null && existing.size() == 1) { 18788 PreferredActivity cur = existing.get(0); 18789 if (DEBUG_PREFERRED) { 18790 Slog.i(TAG, "Checking replace of preferred:"); 18791 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18792 if (!cur.mPref.mAlways) { 18793 Slog.i(TAG, " -- CUR; not mAlways!"); 18794 } else { 18795 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 18796 Slog.i(TAG, " -- CUR: mSet=" 18797 + Arrays.toString(cur.mPref.mSetComponents)); 18798 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 18799 Slog.i(TAG, " -- NEW: mMatch=" 18800 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 18801 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 18802 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 18803 } 18804 } 18805 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 18806 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 18807 && cur.mPref.sameSet(set)) { 18808 // Setting the preferred activity to what it happens to be already 18809 if (DEBUG_PREFERRED) { 18810 Slog.i(TAG, "Replacing with same preferred activity " 18811 + cur.mPref.mShortComponent + " for user " 18812 + userId + ":"); 18813 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18814 } 18815 return; 18816 } 18817 } 18818 18819 if (existing != null) { 18820 if (DEBUG_PREFERRED) { 18821 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 18822 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18823 } 18824 for (int i = 0; i < existing.size(); i++) { 18825 PreferredActivity pa = existing.get(i); 18826 if (DEBUG_PREFERRED) { 18827 Slog.i(TAG, "Removing existing preferred activity " 18828 + pa.mPref.mComponent + ":"); 18829 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 18830 } 18831 pir.removeFilter(pa); 18832 } 18833 } 18834 } 18835 addPreferredActivityInternal(filter, match, set, activity, true, userId, 18836 "Replacing preferred"); 18837 } 18838 } 18839 18840 @Override 18841 public void clearPackagePreferredActivities(String packageName) { 18842 final int uid = Binder.getCallingUid(); 18843 // writer 18844 synchronized (mPackages) { 18845 PackageParser.Package pkg = mPackages.get(packageName); 18846 if (pkg == null || pkg.applicationInfo.uid != uid) { 18847 if (mContext.checkCallingOrSelfPermission( 18848 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18849 != PackageManager.PERMISSION_GRANTED) { 18850 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 18851 < Build.VERSION_CODES.FROYO) { 18852 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 18853 + Binder.getCallingUid()); 18854 return; 18855 } 18856 mContext.enforceCallingOrSelfPermission( 18857 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18858 } 18859 } 18860 18861 int user = UserHandle.getCallingUserId(); 18862 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 18863 scheduleWritePackageRestrictionsLocked(user); 18864 } 18865 } 18866 } 18867 18868 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18869 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 18870 ArrayList<PreferredActivity> removed = null; 18871 boolean changed = false; 18872 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18873 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 18874 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18875 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 18876 continue; 18877 } 18878 Iterator<PreferredActivity> it = pir.filterIterator(); 18879 while (it.hasNext()) { 18880 PreferredActivity pa = it.next(); 18881 // Mark entry for removal only if it matches the package name 18882 // and the entry is of type "always". 18883 if (packageName == null || 18884 (pa.mPref.mComponent.getPackageName().equals(packageName) 18885 && pa.mPref.mAlways)) { 18886 if (removed == null) { 18887 removed = new ArrayList<PreferredActivity>(); 18888 } 18889 removed.add(pa); 18890 } 18891 } 18892 if (removed != null) { 18893 for (int j=0; j<removed.size(); j++) { 18894 PreferredActivity pa = removed.get(j); 18895 pir.removeFilter(pa); 18896 } 18897 changed = true; 18898 } 18899 } 18900 if (changed) { 18901 postPreferredActivityChangedBroadcast(userId); 18902 } 18903 return changed; 18904 } 18905 18906 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18907 private void clearIntentFilterVerificationsLPw(int userId) { 18908 final int packageCount = mPackages.size(); 18909 for (int i = 0; i < packageCount; i++) { 18910 PackageParser.Package pkg = mPackages.valueAt(i); 18911 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 18912 } 18913 } 18914 18915 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18916 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 18917 if (userId == UserHandle.USER_ALL) { 18918 if (mSettings.removeIntentFilterVerificationLPw(packageName, 18919 sUserManager.getUserIds())) { 18920 for (int oneUserId : sUserManager.getUserIds()) { 18921 scheduleWritePackageRestrictionsLocked(oneUserId); 18922 } 18923 } 18924 } else { 18925 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 18926 scheduleWritePackageRestrictionsLocked(userId); 18927 } 18928 } 18929 } 18930 18931 void clearDefaultBrowserIfNeeded(String packageName) { 18932 for (int oneUserId : sUserManager.getUserIds()) { 18933 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 18934 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 18935 if (packageName.equals(defaultBrowserPackageName)) { 18936 setDefaultBrowserPackageName(null, oneUserId); 18937 } 18938 } 18939 } 18940 18941 @Override 18942 public void resetApplicationPreferences(int userId) { 18943 mContext.enforceCallingOrSelfPermission( 18944 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18945 final long identity = Binder.clearCallingIdentity(); 18946 // writer 18947 try { 18948 synchronized (mPackages) { 18949 clearPackagePreferredActivitiesLPw(null, userId); 18950 mSettings.applyDefaultPreferredAppsLPw(this, userId); 18951 // TODO: We have to reset the default SMS and Phone. This requires 18952 // significant refactoring to keep all default apps in the package 18953 // manager (cleaner but more work) or have the services provide 18954 // callbacks to the package manager to request a default app reset. 18955 applyFactoryDefaultBrowserLPw(userId); 18956 clearIntentFilterVerificationsLPw(userId); 18957 primeDomainVerificationsLPw(userId); 18958 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 18959 scheduleWritePackageRestrictionsLocked(userId); 18960 } 18961 resetNetworkPolicies(userId); 18962 } finally { 18963 Binder.restoreCallingIdentity(identity); 18964 } 18965 } 18966 18967 @Override 18968 public int getPreferredActivities(List<IntentFilter> outFilters, 18969 List<ComponentName> outActivities, String packageName) { 18970 18971 int num = 0; 18972 final int userId = UserHandle.getCallingUserId(); 18973 // reader 18974 synchronized (mPackages) { 18975 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 18976 if (pir != null) { 18977 final Iterator<PreferredActivity> it = pir.filterIterator(); 18978 while (it.hasNext()) { 18979 final PreferredActivity pa = it.next(); 18980 if (packageName == null 18981 || (pa.mPref.mComponent.getPackageName().equals(packageName) 18982 && pa.mPref.mAlways)) { 18983 if (outFilters != null) { 18984 outFilters.add(new IntentFilter(pa)); 18985 } 18986 if (outActivities != null) { 18987 outActivities.add(pa.mPref.mComponent); 18988 } 18989 } 18990 } 18991 } 18992 } 18993 18994 return num; 18995 } 18996 18997 @Override 18998 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 18999 int userId) { 19000 int callingUid = Binder.getCallingUid(); 19001 if (callingUid != Process.SYSTEM_UID) { 19002 throw new SecurityException( 19003 "addPersistentPreferredActivity can only be run by the system"); 19004 } 19005 if (filter.countActions() == 0) { 19006 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 19007 return; 19008 } 19009 synchronized (mPackages) { 19010 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 19011 ":"); 19012 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 19013 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 19014 new PersistentPreferredActivity(filter, activity)); 19015 scheduleWritePackageRestrictionsLocked(userId); 19016 postPreferredActivityChangedBroadcast(userId); 19017 } 19018 } 19019 19020 @Override 19021 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 19022 int callingUid = Binder.getCallingUid(); 19023 if (callingUid != Process.SYSTEM_UID) { 19024 throw new SecurityException( 19025 "clearPackagePersistentPreferredActivities can only be run by the system"); 19026 } 19027 ArrayList<PersistentPreferredActivity> removed = null; 19028 boolean changed = false; 19029 synchronized (mPackages) { 19030 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 19031 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 19032 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 19033 .valueAt(i); 19034 if (userId != thisUserId) { 19035 continue; 19036 } 19037 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 19038 while (it.hasNext()) { 19039 PersistentPreferredActivity ppa = it.next(); 19040 // Mark entry for removal only if it matches the package name. 19041 if (ppa.mComponent.getPackageName().equals(packageName)) { 19042 if (removed == null) { 19043 removed = new ArrayList<PersistentPreferredActivity>(); 19044 } 19045 removed.add(ppa); 19046 } 19047 } 19048 if (removed != null) { 19049 for (int j=0; j<removed.size(); j++) { 19050 PersistentPreferredActivity ppa = removed.get(j); 19051 ppir.removeFilter(ppa); 19052 } 19053 changed = true; 19054 } 19055 } 19056 19057 if (changed) { 19058 scheduleWritePackageRestrictionsLocked(userId); 19059 postPreferredActivityChangedBroadcast(userId); 19060 } 19061 } 19062 } 19063 19064 /** 19065 * Common machinery for picking apart a restored XML blob and passing 19066 * it to a caller-supplied functor to be applied to the running system. 19067 */ 19068 private void restoreFromXml(XmlPullParser parser, int userId, 19069 String expectedStartTag, BlobXmlRestorer functor) 19070 throws IOException, XmlPullParserException { 19071 int type; 19072 while ((type = parser.next()) != XmlPullParser.START_TAG 19073 && type != XmlPullParser.END_DOCUMENT) { 19074 } 19075 if (type != XmlPullParser.START_TAG) { 19076 // oops didn't find a start tag?! 19077 if (DEBUG_BACKUP) { 19078 Slog.e(TAG, "Didn't find start tag during restore"); 19079 } 19080 return; 19081 } 19082Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 19083 // this is supposed to be TAG_PREFERRED_BACKUP 19084 if (!expectedStartTag.equals(parser.getName())) { 19085 if (DEBUG_BACKUP) { 19086 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 19087 } 19088 return; 19089 } 19090 19091 // skip interfering stuff, then we're aligned with the backing implementation 19092 while ((type = parser.next()) == XmlPullParser.TEXT) { } 19093Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 19094 functor.apply(parser, userId); 19095 } 19096 19097 private interface BlobXmlRestorer { 19098 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 19099 } 19100 19101 /** 19102 * Non-Binder method, support for the backup/restore mechanism: write the 19103 * full set of preferred activities in its canonical XML format. Returns the 19104 * XML output as a byte array, or null if there is none. 19105 */ 19106 @Override 19107 public byte[] getPreferredActivityBackup(int userId) { 19108 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19109 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 19110 } 19111 19112 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19113 try { 19114 final XmlSerializer serializer = new FastXmlSerializer(); 19115 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19116 serializer.startDocument(null, true); 19117 serializer.startTag(null, TAG_PREFERRED_BACKUP); 19118 19119 synchronized (mPackages) { 19120 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 19121 } 19122 19123 serializer.endTag(null, TAG_PREFERRED_BACKUP); 19124 serializer.endDocument(); 19125 serializer.flush(); 19126 } catch (Exception e) { 19127 if (DEBUG_BACKUP) { 19128 Slog.e(TAG, "Unable to write preferred activities for backup", e); 19129 } 19130 return null; 19131 } 19132 19133 return dataStream.toByteArray(); 19134 } 19135 19136 @Override 19137 public void restorePreferredActivities(byte[] backup, int userId) { 19138 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19139 throw new SecurityException("Only the system may call restorePreferredActivities()"); 19140 } 19141 19142 try { 19143 final XmlPullParser parser = Xml.newPullParser(); 19144 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19145 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 19146 new BlobXmlRestorer() { 19147 @Override 19148 public void apply(XmlPullParser parser, int userId) 19149 throws XmlPullParserException, IOException { 19150 synchronized (mPackages) { 19151 mSettings.readPreferredActivitiesLPw(parser, userId); 19152 } 19153 } 19154 } ); 19155 } catch (Exception e) { 19156 if (DEBUG_BACKUP) { 19157 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19158 } 19159 } 19160 } 19161 19162 /** 19163 * Non-Binder method, support for the backup/restore mechanism: write the 19164 * default browser (etc) settings in its canonical XML format. Returns the default 19165 * browser XML representation as a byte array, or null if there is none. 19166 */ 19167 @Override 19168 public byte[] getDefaultAppsBackup(int userId) { 19169 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19170 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 19171 } 19172 19173 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19174 try { 19175 final XmlSerializer serializer = new FastXmlSerializer(); 19176 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19177 serializer.startDocument(null, true); 19178 serializer.startTag(null, TAG_DEFAULT_APPS); 19179 19180 synchronized (mPackages) { 19181 mSettings.writeDefaultAppsLPr(serializer, userId); 19182 } 19183 19184 serializer.endTag(null, TAG_DEFAULT_APPS); 19185 serializer.endDocument(); 19186 serializer.flush(); 19187 } catch (Exception e) { 19188 if (DEBUG_BACKUP) { 19189 Slog.e(TAG, "Unable to write default apps for backup", e); 19190 } 19191 return null; 19192 } 19193 19194 return dataStream.toByteArray(); 19195 } 19196 19197 @Override 19198 public void restoreDefaultApps(byte[] backup, int userId) { 19199 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19200 throw new SecurityException("Only the system may call restoreDefaultApps()"); 19201 } 19202 19203 try { 19204 final XmlPullParser parser = Xml.newPullParser(); 19205 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19206 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 19207 new BlobXmlRestorer() { 19208 @Override 19209 public void apply(XmlPullParser parser, int userId) 19210 throws XmlPullParserException, IOException { 19211 synchronized (mPackages) { 19212 mSettings.readDefaultAppsLPw(parser, userId); 19213 } 19214 } 19215 } ); 19216 } catch (Exception e) { 19217 if (DEBUG_BACKUP) { 19218 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 19219 } 19220 } 19221 } 19222 19223 @Override 19224 public byte[] getIntentFilterVerificationBackup(int userId) { 19225 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19226 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 19227 } 19228 19229 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19230 try { 19231 final XmlSerializer serializer = new FastXmlSerializer(); 19232 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19233 serializer.startDocument(null, true); 19234 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 19235 19236 synchronized (mPackages) { 19237 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 19238 } 19239 19240 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 19241 serializer.endDocument(); 19242 serializer.flush(); 19243 } catch (Exception e) { 19244 if (DEBUG_BACKUP) { 19245 Slog.e(TAG, "Unable to write default apps for backup", e); 19246 } 19247 return null; 19248 } 19249 19250 return dataStream.toByteArray(); 19251 } 19252 19253 @Override 19254 public void restoreIntentFilterVerification(byte[] backup, int userId) { 19255 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19256 throw new SecurityException("Only the system may call restorePreferredActivities()"); 19257 } 19258 19259 try { 19260 final XmlPullParser parser = Xml.newPullParser(); 19261 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19262 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 19263 new BlobXmlRestorer() { 19264 @Override 19265 public void apply(XmlPullParser parser, int userId) 19266 throws XmlPullParserException, IOException { 19267 synchronized (mPackages) { 19268 mSettings.readAllDomainVerificationsLPr(parser, userId); 19269 mSettings.writeLPr(); 19270 } 19271 } 19272 } ); 19273 } catch (Exception e) { 19274 if (DEBUG_BACKUP) { 19275 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19276 } 19277 } 19278 } 19279 19280 @Override 19281 public byte[] getPermissionGrantBackup(int userId) { 19282 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19283 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 19284 } 19285 19286 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19287 try { 19288 final XmlSerializer serializer = new FastXmlSerializer(); 19289 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19290 serializer.startDocument(null, true); 19291 serializer.startTag(null, TAG_PERMISSION_BACKUP); 19292 19293 synchronized (mPackages) { 19294 serializeRuntimePermissionGrantsLPr(serializer, userId); 19295 } 19296 19297 serializer.endTag(null, TAG_PERMISSION_BACKUP); 19298 serializer.endDocument(); 19299 serializer.flush(); 19300 } catch (Exception e) { 19301 if (DEBUG_BACKUP) { 19302 Slog.e(TAG, "Unable to write default apps for backup", e); 19303 } 19304 return null; 19305 } 19306 19307 return dataStream.toByteArray(); 19308 } 19309 19310 @Override 19311 public void restorePermissionGrants(byte[] backup, int userId) { 19312 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19313 throw new SecurityException("Only the system may call restorePermissionGrants()"); 19314 } 19315 19316 try { 19317 final XmlPullParser parser = Xml.newPullParser(); 19318 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19319 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 19320 new BlobXmlRestorer() { 19321 @Override 19322 public void apply(XmlPullParser parser, int userId) 19323 throws XmlPullParserException, IOException { 19324 synchronized (mPackages) { 19325 processRestoredPermissionGrantsLPr(parser, userId); 19326 } 19327 } 19328 } ); 19329 } catch (Exception e) { 19330 if (DEBUG_BACKUP) { 19331 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19332 } 19333 } 19334 } 19335 19336 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 19337 throws IOException { 19338 serializer.startTag(null, TAG_ALL_GRANTS); 19339 19340 final int N = mSettings.mPackages.size(); 19341 for (int i = 0; i < N; i++) { 19342 final PackageSetting ps = mSettings.mPackages.valueAt(i); 19343 boolean pkgGrantsKnown = false; 19344 19345 PermissionsState packagePerms = ps.getPermissionsState(); 19346 19347 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 19348 final int grantFlags = state.getFlags(); 19349 // only look at grants that are not system/policy fixed 19350 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 19351 final boolean isGranted = state.isGranted(); 19352 // And only back up the user-twiddled state bits 19353 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 19354 final String packageName = mSettings.mPackages.keyAt(i); 19355 if (!pkgGrantsKnown) { 19356 serializer.startTag(null, TAG_GRANT); 19357 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 19358 pkgGrantsKnown = true; 19359 } 19360 19361 final boolean userSet = 19362 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 19363 final boolean userFixed = 19364 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 19365 final boolean revoke = 19366 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 19367 19368 serializer.startTag(null, TAG_PERMISSION); 19369 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 19370 if (isGranted) { 19371 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 19372 } 19373 if (userSet) { 19374 serializer.attribute(null, ATTR_USER_SET, "true"); 19375 } 19376 if (userFixed) { 19377 serializer.attribute(null, ATTR_USER_FIXED, "true"); 19378 } 19379 if (revoke) { 19380 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 19381 } 19382 serializer.endTag(null, TAG_PERMISSION); 19383 } 19384 } 19385 } 19386 19387 if (pkgGrantsKnown) { 19388 serializer.endTag(null, TAG_GRANT); 19389 } 19390 } 19391 19392 serializer.endTag(null, TAG_ALL_GRANTS); 19393 } 19394 19395 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 19396 throws XmlPullParserException, IOException { 19397 String pkgName = null; 19398 int outerDepth = parser.getDepth(); 19399 int type; 19400 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 19401 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 19402 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 19403 continue; 19404 } 19405 19406 final String tagName = parser.getName(); 19407 if (tagName.equals(TAG_GRANT)) { 19408 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 19409 if (DEBUG_BACKUP) { 19410 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 19411 } 19412 } else if (tagName.equals(TAG_PERMISSION)) { 19413 19414 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 19415 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 19416 19417 int newFlagSet = 0; 19418 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 19419 newFlagSet |= FLAG_PERMISSION_USER_SET; 19420 } 19421 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 19422 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 19423 } 19424 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 19425 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 19426 } 19427 if (DEBUG_BACKUP) { 19428 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 19429 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 19430 } 19431 final PackageSetting ps = mSettings.mPackages.get(pkgName); 19432 if (ps != null) { 19433 // Already installed so we apply the grant immediately 19434 if (DEBUG_BACKUP) { 19435 Slog.v(TAG, " + already installed; applying"); 19436 } 19437 PermissionsState perms = ps.getPermissionsState(); 19438 BasePermission bp = mSettings.mPermissions.get(permName); 19439 if (bp != null) { 19440 if (isGranted) { 19441 perms.grantRuntimePermission(bp, userId); 19442 } 19443 if (newFlagSet != 0) { 19444 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 19445 } 19446 } 19447 } else { 19448 // Need to wait for post-restore install to apply the grant 19449 if (DEBUG_BACKUP) { 19450 Slog.v(TAG, " - not yet installed; saving for later"); 19451 } 19452 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 19453 isGranted, newFlagSet, userId); 19454 } 19455 } else { 19456 PackageManagerService.reportSettingsProblem(Log.WARN, 19457 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 19458 XmlUtils.skipCurrentTag(parser); 19459 } 19460 } 19461 19462 scheduleWriteSettingsLocked(); 19463 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 19464 } 19465 19466 @Override 19467 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 19468 int sourceUserId, int targetUserId, int flags) { 19469 mContext.enforceCallingOrSelfPermission( 19470 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 19471 int callingUid = Binder.getCallingUid(); 19472 enforceOwnerRights(ownerPackage, callingUid); 19473 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 19474 if (intentFilter.countActions() == 0) { 19475 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 19476 return; 19477 } 19478 synchronized (mPackages) { 19479 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 19480 ownerPackage, targetUserId, flags); 19481 CrossProfileIntentResolver resolver = 19482 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 19483 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 19484 // We have all those whose filter is equal. Now checking if the rest is equal as well. 19485 if (existing != null) { 19486 int size = existing.size(); 19487 for (int i = 0; i < size; i++) { 19488 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 19489 return; 19490 } 19491 } 19492 } 19493 resolver.addFilter(newFilter); 19494 scheduleWritePackageRestrictionsLocked(sourceUserId); 19495 } 19496 } 19497 19498 @Override 19499 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 19500 mContext.enforceCallingOrSelfPermission( 19501 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 19502 int callingUid = Binder.getCallingUid(); 19503 enforceOwnerRights(ownerPackage, callingUid); 19504 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 19505 synchronized (mPackages) { 19506 CrossProfileIntentResolver resolver = 19507 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 19508 ArraySet<CrossProfileIntentFilter> set = 19509 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 19510 for (CrossProfileIntentFilter filter : set) { 19511 if (filter.getOwnerPackage().equals(ownerPackage)) { 19512 resolver.removeFilter(filter); 19513 } 19514 } 19515 scheduleWritePackageRestrictionsLocked(sourceUserId); 19516 } 19517 } 19518 19519 // Enforcing that callingUid is owning pkg on userId 19520 private void enforceOwnerRights(String pkg, int callingUid) { 19521 // The system owns everything. 19522 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 19523 return; 19524 } 19525 int callingUserId = UserHandle.getUserId(callingUid); 19526 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 19527 if (pi == null) { 19528 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 19529 + callingUserId); 19530 } 19531 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 19532 throw new SecurityException("Calling uid " + callingUid 19533 + " does not own package " + pkg); 19534 } 19535 } 19536 19537 @Override 19538 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 19539 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 19540 } 19541 19542 /** 19543 * Report the 'Home' activity which is currently set as "always use this one". If non is set 19544 * then reports the most likely home activity or null if there are more than one. 19545 */ 19546 public ComponentName getDefaultHomeActivity(int userId) { 19547 List<ResolveInfo> allHomeCandidates = new ArrayList<>(); 19548 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId); 19549 if (cn != null) { 19550 return cn; 19551 } 19552 19553 // Find the launcher with the highest priority and return that component if there are no 19554 // other home activity with the same priority. 19555 int lastPriority = Integer.MIN_VALUE; 19556 ComponentName lastComponent = null; 19557 final int size = allHomeCandidates.size(); 19558 for (int i = 0; i < size; i++) { 19559 final ResolveInfo ri = allHomeCandidates.get(i); 19560 if (ri.priority > lastPriority) { 19561 lastComponent = ri.activityInfo.getComponentName(); 19562 lastPriority = ri.priority; 19563 } else if (ri.priority == lastPriority) { 19564 // Two components found with same priority. 19565 lastComponent = null; 19566 } 19567 } 19568 return lastComponent; 19569 } 19570 19571 private Intent getHomeIntent() { 19572 Intent intent = new Intent(Intent.ACTION_MAIN); 19573 intent.addCategory(Intent.CATEGORY_HOME); 19574 intent.addCategory(Intent.CATEGORY_DEFAULT); 19575 return intent; 19576 } 19577 19578 private IntentFilter getHomeFilter() { 19579 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 19580 filter.addCategory(Intent.CATEGORY_HOME); 19581 filter.addCategory(Intent.CATEGORY_DEFAULT); 19582 return filter; 19583 } 19584 19585 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 19586 int userId) { 19587 Intent intent = getHomeIntent(); 19588 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 19589 PackageManager.GET_META_DATA, userId); 19590 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 19591 true, false, false, userId); 19592 19593 allHomeCandidates.clear(); 19594 if (list != null) { 19595 for (ResolveInfo ri : list) { 19596 allHomeCandidates.add(ri); 19597 } 19598 } 19599 return (preferred == null || preferred.activityInfo == null) 19600 ? null 19601 : new ComponentName(preferred.activityInfo.packageName, 19602 preferred.activityInfo.name); 19603 } 19604 19605 @Override 19606 public void setHomeActivity(ComponentName comp, int userId) { 19607 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 19608 getHomeActivitiesAsUser(homeActivities, userId); 19609 19610 boolean found = false; 19611 19612 final int size = homeActivities.size(); 19613 final ComponentName[] set = new ComponentName[size]; 19614 for (int i = 0; i < size; i++) { 19615 final ResolveInfo candidate = homeActivities.get(i); 19616 final ActivityInfo info = candidate.activityInfo; 19617 final ComponentName activityName = new ComponentName(info.packageName, info.name); 19618 set[i] = activityName; 19619 if (!found && activityName.equals(comp)) { 19620 found = true; 19621 } 19622 } 19623 if (!found) { 19624 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 19625 + userId); 19626 } 19627 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 19628 set, comp, userId); 19629 } 19630 19631 private @Nullable String getSetupWizardPackageName() { 19632 final Intent intent = new Intent(Intent.ACTION_MAIN); 19633 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 19634 19635 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 19636 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 19637 | MATCH_DISABLED_COMPONENTS, 19638 UserHandle.myUserId()); 19639 if (matches.size() == 1) { 19640 return matches.get(0).getComponentInfo().packageName; 19641 } else { 19642 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 19643 + ": matches=" + matches); 19644 return null; 19645 } 19646 } 19647 19648 private @Nullable String getStorageManagerPackageName() { 19649 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); 19650 19651 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 19652 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 19653 | MATCH_DISABLED_COMPONENTS, 19654 UserHandle.myUserId()); 19655 if (matches.size() == 1) { 19656 return matches.get(0).getComponentInfo().packageName; 19657 } else { 19658 Slog.e(TAG, "There should probably be exactly one storage manager; found " 19659 + matches.size() + ": matches=" + matches); 19660 return null; 19661 } 19662 } 19663 19664 @Override 19665 public void setApplicationEnabledSetting(String appPackageName, 19666 int newState, int flags, int userId, String callingPackage) { 19667 if (!sUserManager.exists(userId)) return; 19668 if (callingPackage == null) { 19669 callingPackage = Integer.toString(Binder.getCallingUid()); 19670 } 19671 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 19672 } 19673 19674 @Override 19675 public void setComponentEnabledSetting(ComponentName componentName, 19676 int newState, int flags, int userId) { 19677 if (!sUserManager.exists(userId)) return; 19678 setEnabledSetting(componentName.getPackageName(), 19679 componentName.getClassName(), newState, flags, userId, null); 19680 } 19681 19682 private void setEnabledSetting(final String packageName, String className, int newState, 19683 final int flags, int userId, String callingPackage) { 19684 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 19685 || newState == COMPONENT_ENABLED_STATE_ENABLED 19686 || newState == COMPONENT_ENABLED_STATE_DISABLED 19687 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 19688 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 19689 throw new IllegalArgumentException("Invalid new component state: " 19690 + newState); 19691 } 19692 PackageSetting pkgSetting; 19693 final int uid = Binder.getCallingUid(); 19694 final int permission; 19695 if (uid == Process.SYSTEM_UID) { 19696 permission = PackageManager.PERMISSION_GRANTED; 19697 } else { 19698 permission = mContext.checkCallingOrSelfPermission( 19699 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 19700 } 19701 enforceCrossUserPermission(uid, userId, 19702 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 19703 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 19704 boolean sendNow = false; 19705 boolean isApp = (className == null); 19706 String componentName = isApp ? packageName : className; 19707 int packageUid = -1; 19708 ArrayList<String> components; 19709 19710 // writer 19711 synchronized (mPackages) { 19712 pkgSetting = mSettings.mPackages.get(packageName); 19713 if (pkgSetting == null) { 19714 if (className == null) { 19715 throw new IllegalArgumentException("Unknown package: " + packageName); 19716 } 19717 throw new IllegalArgumentException( 19718 "Unknown component: " + packageName + "/" + className); 19719 } 19720 } 19721 19722 // Limit who can change which apps 19723 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 19724 // Don't allow apps that don't have permission to modify other apps 19725 if (!allowedByPermission) { 19726 throw new SecurityException( 19727 "Permission Denial: attempt to change component state from pid=" 19728 + Binder.getCallingPid() 19729 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 19730 } 19731 // Don't allow changing protected packages. 19732 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 19733 throw new SecurityException("Cannot disable a protected package: " + packageName); 19734 } 19735 } 19736 19737 synchronized (mPackages) { 19738 if (uid == Process.SHELL_UID 19739 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { 19740 // Shell can only change whole packages between ENABLED and DISABLED_USER states 19741 // unless it is a test package. 19742 int oldState = pkgSetting.getEnabled(userId); 19743 if (className == null 19744 && 19745 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 19746 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 19747 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 19748 && 19749 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 19750 || newState == COMPONENT_ENABLED_STATE_DEFAULT 19751 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 19752 // ok 19753 } else { 19754 throw new SecurityException( 19755 "Shell cannot change component state for " + packageName + "/" 19756 + className + " to " + newState); 19757 } 19758 } 19759 if (className == null) { 19760 // We're dealing with an application/package level state change 19761 if (pkgSetting.getEnabled(userId) == newState) { 19762 // Nothing to do 19763 return; 19764 } 19765 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 19766 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 19767 // Don't care about who enables an app. 19768 callingPackage = null; 19769 } 19770 pkgSetting.setEnabled(newState, userId, callingPackage); 19771 // pkgSetting.pkg.mSetEnabled = newState; 19772 } else { 19773 // We're dealing with a component level state change 19774 // First, verify that this is a valid class name. 19775 PackageParser.Package pkg = pkgSetting.pkg; 19776 if (pkg == null || !pkg.hasComponentClassName(className)) { 19777 if (pkg != null && 19778 pkg.applicationInfo.targetSdkVersion >= 19779 Build.VERSION_CODES.JELLY_BEAN) { 19780 throw new IllegalArgumentException("Component class " + className 19781 + " does not exist in " + packageName); 19782 } else { 19783 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 19784 + className + " does not exist in " + packageName); 19785 } 19786 } 19787 switch (newState) { 19788 case COMPONENT_ENABLED_STATE_ENABLED: 19789 if (!pkgSetting.enableComponentLPw(className, userId)) { 19790 return; 19791 } 19792 break; 19793 case COMPONENT_ENABLED_STATE_DISABLED: 19794 if (!pkgSetting.disableComponentLPw(className, userId)) { 19795 return; 19796 } 19797 break; 19798 case COMPONENT_ENABLED_STATE_DEFAULT: 19799 if (!pkgSetting.restoreComponentLPw(className, userId)) { 19800 return; 19801 } 19802 break; 19803 default: 19804 Slog.e(TAG, "Invalid new component state: " + newState); 19805 return; 19806 } 19807 } 19808 scheduleWritePackageRestrictionsLocked(userId); 19809 updateSequenceNumberLP(packageName, new int[] { userId }); 19810 components = mPendingBroadcasts.get(userId, packageName); 19811 final boolean newPackage = components == null; 19812 if (newPackage) { 19813 components = new ArrayList<String>(); 19814 } 19815 if (!components.contains(componentName)) { 19816 components.add(componentName); 19817 } 19818 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 19819 sendNow = true; 19820 // Purge entry from pending broadcast list if another one exists already 19821 // since we are sending one right away. 19822 mPendingBroadcasts.remove(userId, packageName); 19823 } else { 19824 if (newPackage) { 19825 mPendingBroadcasts.put(userId, packageName, components); 19826 } 19827 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 19828 // Schedule a message 19829 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 19830 } 19831 } 19832 } 19833 19834 long callingId = Binder.clearCallingIdentity(); 19835 try { 19836 if (sendNow) { 19837 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 19838 sendPackageChangedBroadcast(packageName, 19839 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 19840 } 19841 } finally { 19842 Binder.restoreCallingIdentity(callingId); 19843 } 19844 } 19845 19846 @Override 19847 public void flushPackageRestrictionsAsUser(int userId) { 19848 if (!sUserManager.exists(userId)) { 19849 return; 19850 } 19851 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 19852 false /* checkShell */, "flushPackageRestrictions"); 19853 synchronized (mPackages) { 19854 mSettings.writePackageRestrictionsLPr(userId); 19855 mDirtyUsers.remove(userId); 19856 if (mDirtyUsers.isEmpty()) { 19857 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 19858 } 19859 } 19860 } 19861 19862 private void sendPackageChangedBroadcast(String packageName, 19863 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 19864 if (DEBUG_INSTALL) 19865 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 19866 + componentNames); 19867 Bundle extras = new Bundle(4); 19868 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 19869 String nameList[] = new String[componentNames.size()]; 19870 componentNames.toArray(nameList); 19871 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 19872 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 19873 extras.putInt(Intent.EXTRA_UID, packageUid); 19874 // If this is not reporting a change of the overall package, then only send it 19875 // to registered receivers. We don't want to launch a swath of apps for every 19876 // little component state change. 19877 final int flags = !componentNames.contains(packageName) 19878 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 19879 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 19880 new int[] {UserHandle.getUserId(packageUid)}); 19881 } 19882 19883 @Override 19884 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 19885 if (!sUserManager.exists(userId)) return; 19886 final int uid = Binder.getCallingUid(); 19887 final int permission = mContext.checkCallingOrSelfPermission( 19888 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 19889 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 19890 enforceCrossUserPermission(uid, userId, 19891 true /* requireFullPermission */, true /* checkShell */, "stop package"); 19892 // writer 19893 synchronized (mPackages) { 19894 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 19895 allowedByPermission, uid, userId)) { 19896 scheduleWritePackageRestrictionsLocked(userId); 19897 } 19898 } 19899 } 19900 19901 @Override 19902 public String getInstallerPackageName(String packageName) { 19903 // reader 19904 synchronized (mPackages) { 19905 return mSettings.getInstallerPackageNameLPr(packageName); 19906 } 19907 } 19908 19909 public boolean isOrphaned(String packageName) { 19910 // reader 19911 synchronized (mPackages) { 19912 return mSettings.isOrphaned(packageName); 19913 } 19914 } 19915 19916 @Override 19917 public int getApplicationEnabledSetting(String packageName, int userId) { 19918 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 19919 int uid = Binder.getCallingUid(); 19920 enforceCrossUserPermission(uid, userId, 19921 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 19922 // reader 19923 synchronized (mPackages) { 19924 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 19925 } 19926 } 19927 19928 @Override 19929 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 19930 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 19931 int uid = Binder.getCallingUid(); 19932 enforceCrossUserPermission(uid, userId, 19933 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 19934 // reader 19935 synchronized (mPackages) { 19936 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 19937 } 19938 } 19939 19940 @Override 19941 public void enterSafeMode() { 19942 enforceSystemOrRoot("Only the system can request entering safe mode"); 19943 19944 if (!mSystemReady) { 19945 mSafeMode = true; 19946 } 19947 } 19948 19949 @Override 19950 public void systemReady() { 19951 mSystemReady = true; 19952 19953 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 19954 // disabled after already being started. 19955 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 19956 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 19957 19958 // Read the compatibilty setting when the system is ready. 19959 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 19960 mContext.getContentResolver(), 19961 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 19962 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 19963 if (DEBUG_SETTINGS) { 19964 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 19965 } 19966 19967 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 19968 19969 synchronized (mPackages) { 19970 // Verify that all of the preferred activity components actually 19971 // exist. It is possible for applications to be updated and at 19972 // that point remove a previously declared activity component that 19973 // had been set as a preferred activity. We try to clean this up 19974 // the next time we encounter that preferred activity, but it is 19975 // possible for the user flow to never be able to return to that 19976 // situation so here we do a sanity check to make sure we haven't 19977 // left any junk around. 19978 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 19979 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 19980 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 19981 removed.clear(); 19982 for (PreferredActivity pa : pir.filterSet()) { 19983 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 19984 removed.add(pa); 19985 } 19986 } 19987 if (removed.size() > 0) { 19988 for (int r=0; r<removed.size(); r++) { 19989 PreferredActivity pa = removed.get(r); 19990 Slog.w(TAG, "Removing dangling preferred activity: " 19991 + pa.mPref.mComponent); 19992 pir.removeFilter(pa); 19993 } 19994 mSettings.writePackageRestrictionsLPr( 19995 mSettings.mPreferredActivities.keyAt(i)); 19996 } 19997 } 19998 19999 for (int userId : UserManagerService.getInstance().getUserIds()) { 20000 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 20001 grantPermissionsUserIds = ArrayUtils.appendInt( 20002 grantPermissionsUserIds, userId); 20003 } 20004 } 20005 } 20006 sUserManager.systemReady(); 20007 20008 // If we upgraded grant all default permissions before kicking off. 20009 for (int userId : grantPermissionsUserIds) { 20010 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 20011 } 20012 20013 // If we did not grant default permissions, we preload from this the 20014 // default permission exceptions lazily to ensure we don't hit the 20015 // disk on a new user creation. 20016 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 20017 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 20018 } 20019 20020 // Kick off any messages waiting for system ready 20021 if (mPostSystemReadyMessages != null) { 20022 for (Message msg : mPostSystemReadyMessages) { 20023 msg.sendToTarget(); 20024 } 20025 mPostSystemReadyMessages = null; 20026 } 20027 20028 // Watch for external volumes that come and go over time 20029 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20030 storage.registerListener(mStorageListener); 20031 20032 mInstallerService.systemReady(); 20033 mPackageDexOptimizer.systemReady(); 20034 20035 StorageManagerInternal StorageManagerInternal = LocalServices.getService( 20036 StorageManagerInternal.class); 20037 StorageManagerInternal.addExternalStoragePolicy( 20038 new StorageManagerInternal.ExternalStorageMountPolicy() { 20039 @Override 20040 public int getMountMode(int uid, String packageName) { 20041 if (Process.isIsolated(uid)) { 20042 return Zygote.MOUNT_EXTERNAL_NONE; 20043 } 20044 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 20045 return Zygote.MOUNT_EXTERNAL_DEFAULT; 20046 } 20047 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 20048 return Zygote.MOUNT_EXTERNAL_DEFAULT; 20049 } 20050 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 20051 return Zygote.MOUNT_EXTERNAL_READ; 20052 } 20053 return Zygote.MOUNT_EXTERNAL_WRITE; 20054 } 20055 20056 @Override 20057 public boolean hasExternalStorage(int uid, String packageName) { 20058 return true; 20059 } 20060 }); 20061 20062 // Now that we're mostly running, clean up stale users and apps 20063 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 20064 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 20065 20066 if (mPrivappPermissionsViolations != null) { 20067 Slog.wtf(TAG,"Signature|privileged permissions not in " 20068 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations); 20069 mPrivappPermissionsViolations = null; 20070 } 20071 } 20072 20073 public void waitForAppDataPrepared() { 20074 if (mPrepareAppDataFuture == null) { 20075 return; 20076 } 20077 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData"); 20078 mPrepareAppDataFuture = null; 20079 } 20080 20081 @Override 20082 public boolean isSafeMode() { 20083 return mSafeMode; 20084 } 20085 20086 @Override 20087 public boolean hasSystemUidErrors() { 20088 return mHasSystemUidErrors; 20089 } 20090 20091 static String arrayToString(int[] array) { 20092 StringBuffer buf = new StringBuffer(128); 20093 buf.append('['); 20094 if (array != null) { 20095 for (int i=0; i<array.length; i++) { 20096 if (i > 0) buf.append(", "); 20097 buf.append(array[i]); 20098 } 20099 } 20100 buf.append(']'); 20101 return buf.toString(); 20102 } 20103 20104 static class DumpState { 20105 public static final int DUMP_LIBS = 1 << 0; 20106 public static final int DUMP_FEATURES = 1 << 1; 20107 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 20108 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 20109 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 20110 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 20111 public static final int DUMP_PERMISSIONS = 1 << 6; 20112 public static final int DUMP_PACKAGES = 1 << 7; 20113 public static final int DUMP_SHARED_USERS = 1 << 8; 20114 public static final int DUMP_MESSAGES = 1 << 9; 20115 public static final int DUMP_PROVIDERS = 1 << 10; 20116 public static final int DUMP_VERIFIERS = 1 << 11; 20117 public static final int DUMP_PREFERRED = 1 << 12; 20118 public static final int DUMP_PREFERRED_XML = 1 << 13; 20119 public static final int DUMP_KEYSETS = 1 << 14; 20120 public static final int DUMP_VERSION = 1 << 15; 20121 public static final int DUMP_INSTALLS = 1 << 16; 20122 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 20123 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 20124 public static final int DUMP_FROZEN = 1 << 19; 20125 public static final int DUMP_DEXOPT = 1 << 20; 20126 public static final int DUMP_COMPILER_STATS = 1 << 21; 20127 public static final int DUMP_ENABLED_OVERLAYS = 1 << 22; 20128 20129 public static final int OPTION_SHOW_FILTERS = 1 << 0; 20130 20131 private int mTypes; 20132 20133 private int mOptions; 20134 20135 private boolean mTitlePrinted; 20136 20137 private SharedUserSetting mSharedUser; 20138 20139 public boolean isDumping(int type) { 20140 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 20141 return true; 20142 } 20143 20144 return (mTypes & type) != 0; 20145 } 20146 20147 public void setDump(int type) { 20148 mTypes |= type; 20149 } 20150 20151 public boolean isOptionEnabled(int option) { 20152 return (mOptions & option) != 0; 20153 } 20154 20155 public void setOptionEnabled(int option) { 20156 mOptions |= option; 20157 } 20158 20159 public boolean onTitlePrinted() { 20160 final boolean printed = mTitlePrinted; 20161 mTitlePrinted = true; 20162 return printed; 20163 } 20164 20165 public boolean getTitlePrinted() { 20166 return mTitlePrinted; 20167 } 20168 20169 public void setTitlePrinted(boolean enabled) { 20170 mTitlePrinted = enabled; 20171 } 20172 20173 public SharedUserSetting getSharedUser() { 20174 return mSharedUser; 20175 } 20176 20177 public void setSharedUser(SharedUserSetting user) { 20178 mSharedUser = user; 20179 } 20180 } 20181 20182 @Override 20183 public void onShellCommand(FileDescriptor in, FileDescriptor out, 20184 FileDescriptor err, String[] args, ShellCallback callback, 20185 ResultReceiver resultReceiver) { 20186 (new PackageManagerShellCommand(this)).exec( 20187 this, in, out, err, args, callback, resultReceiver); 20188 } 20189 20190 @Override 20191 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 20192 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 20193 != PackageManager.PERMISSION_GRANTED) { 20194 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 20195 + Binder.getCallingPid() 20196 + ", uid=" + Binder.getCallingUid() 20197 + " without permission " 20198 + android.Manifest.permission.DUMP); 20199 return; 20200 } 20201 20202 DumpState dumpState = new DumpState(); 20203 boolean fullPreferred = false; 20204 boolean checkin = false; 20205 20206 String packageName = null; 20207 ArraySet<String> permissionNames = null; 20208 20209 int opti = 0; 20210 while (opti < args.length) { 20211 String opt = args[opti]; 20212 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 20213 break; 20214 } 20215 opti++; 20216 20217 if ("-a".equals(opt)) { 20218 // Right now we only know how to print all. 20219 } else if ("-h".equals(opt)) { 20220 pw.println("Package manager dump options:"); 20221 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 20222 pw.println(" --checkin: dump for a checkin"); 20223 pw.println(" -f: print details of intent filters"); 20224 pw.println(" -h: print this help"); 20225 pw.println(" cmd may be one of:"); 20226 pw.println(" l[ibraries]: list known shared libraries"); 20227 pw.println(" f[eatures]: list device features"); 20228 pw.println(" k[eysets]: print known keysets"); 20229 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 20230 pw.println(" perm[issions]: dump permissions"); 20231 pw.println(" permission [name ...]: dump declaration and use of given permission"); 20232 pw.println(" pref[erred]: print preferred package settings"); 20233 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 20234 pw.println(" prov[iders]: dump content providers"); 20235 pw.println(" p[ackages]: dump installed packages"); 20236 pw.println(" s[hared-users]: dump shared user IDs"); 20237 pw.println(" m[essages]: print collected runtime messages"); 20238 pw.println(" v[erifiers]: print package verifier info"); 20239 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 20240 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 20241 pw.println(" version: print database version info"); 20242 pw.println(" write: write current settings now"); 20243 pw.println(" installs: details about install sessions"); 20244 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 20245 pw.println(" dexopt: dump dexopt state"); 20246 pw.println(" compiler-stats: dump compiler statistics"); 20247 pw.println(" enabled-overlays: dump list of enabled overlay packages"); 20248 pw.println(" <package.name>: info about given package"); 20249 return; 20250 } else if ("--checkin".equals(opt)) { 20251 checkin = true; 20252 } else if ("-f".equals(opt)) { 20253 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 20254 } else if ("--proto".equals(opt)) { 20255 dumpProto(fd); 20256 return; 20257 } else { 20258 pw.println("Unknown argument: " + opt + "; use -h for help"); 20259 } 20260 } 20261 20262 // Is the caller requesting to dump a particular piece of data? 20263 if (opti < args.length) { 20264 String cmd = args[opti]; 20265 opti++; 20266 // Is this a package name? 20267 if ("android".equals(cmd) || cmd.contains(".")) { 20268 packageName = cmd; 20269 // When dumping a single package, we always dump all of its 20270 // filter information since the amount of data will be reasonable. 20271 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 20272 } else if ("check-permission".equals(cmd)) { 20273 if (opti >= args.length) { 20274 pw.println("Error: check-permission missing permission argument"); 20275 return; 20276 } 20277 String perm = args[opti]; 20278 opti++; 20279 if (opti >= args.length) { 20280 pw.println("Error: check-permission missing package argument"); 20281 return; 20282 } 20283 20284 String pkg = args[opti]; 20285 opti++; 20286 int user = UserHandle.getUserId(Binder.getCallingUid()); 20287 if (opti < args.length) { 20288 try { 20289 user = Integer.parseInt(args[opti]); 20290 } catch (NumberFormatException e) { 20291 pw.println("Error: check-permission user argument is not a number: " 20292 + args[opti]); 20293 return; 20294 } 20295 } 20296 20297 // Normalize package name to handle renamed packages and static libs 20298 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST); 20299 20300 pw.println(checkPermission(perm, pkg, user)); 20301 return; 20302 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 20303 dumpState.setDump(DumpState.DUMP_LIBS); 20304 } else if ("f".equals(cmd) || "features".equals(cmd)) { 20305 dumpState.setDump(DumpState.DUMP_FEATURES); 20306 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 20307 if (opti >= args.length) { 20308 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 20309 | DumpState.DUMP_SERVICE_RESOLVERS 20310 | DumpState.DUMP_RECEIVER_RESOLVERS 20311 | DumpState.DUMP_CONTENT_RESOLVERS); 20312 } else { 20313 while (opti < args.length) { 20314 String name = args[opti]; 20315 if ("a".equals(name) || "activity".equals(name)) { 20316 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 20317 } else if ("s".equals(name) || "service".equals(name)) { 20318 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 20319 } else if ("r".equals(name) || "receiver".equals(name)) { 20320 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 20321 } else if ("c".equals(name) || "content".equals(name)) { 20322 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 20323 } else { 20324 pw.println("Error: unknown resolver table type: " + name); 20325 return; 20326 } 20327 opti++; 20328 } 20329 } 20330 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 20331 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 20332 } else if ("permission".equals(cmd)) { 20333 if (opti >= args.length) { 20334 pw.println("Error: permission requires permission name"); 20335 return; 20336 } 20337 permissionNames = new ArraySet<>(); 20338 while (opti < args.length) { 20339 permissionNames.add(args[opti]); 20340 opti++; 20341 } 20342 dumpState.setDump(DumpState.DUMP_PERMISSIONS 20343 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 20344 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 20345 dumpState.setDump(DumpState.DUMP_PREFERRED); 20346 } else if ("preferred-xml".equals(cmd)) { 20347 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 20348 if (opti < args.length && "--full".equals(args[opti])) { 20349 fullPreferred = true; 20350 opti++; 20351 } 20352 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 20353 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 20354 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 20355 dumpState.setDump(DumpState.DUMP_PACKAGES); 20356 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 20357 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 20358 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 20359 dumpState.setDump(DumpState.DUMP_PROVIDERS); 20360 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 20361 dumpState.setDump(DumpState.DUMP_MESSAGES); 20362 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 20363 dumpState.setDump(DumpState.DUMP_VERIFIERS); 20364 } else if ("i".equals(cmd) || "ifv".equals(cmd) 20365 || "intent-filter-verifiers".equals(cmd)) { 20366 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 20367 } else if ("version".equals(cmd)) { 20368 dumpState.setDump(DumpState.DUMP_VERSION); 20369 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 20370 dumpState.setDump(DumpState.DUMP_KEYSETS); 20371 } else if ("installs".equals(cmd)) { 20372 dumpState.setDump(DumpState.DUMP_INSTALLS); 20373 } else if ("frozen".equals(cmd)) { 20374 dumpState.setDump(DumpState.DUMP_FROZEN); 20375 } else if ("dexopt".equals(cmd)) { 20376 dumpState.setDump(DumpState.DUMP_DEXOPT); 20377 } else if ("compiler-stats".equals(cmd)) { 20378 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 20379 } else if ("enabled-overlays".equals(cmd)) { 20380 dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS); 20381 } else if ("write".equals(cmd)) { 20382 synchronized (mPackages) { 20383 mSettings.writeLPr(); 20384 pw.println("Settings written."); 20385 return; 20386 } 20387 } 20388 } 20389 20390 if (checkin) { 20391 pw.println("vers,1"); 20392 } 20393 20394 // reader 20395 synchronized (mPackages) { 20396 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 20397 if (!checkin) { 20398 if (dumpState.onTitlePrinted()) 20399 pw.println(); 20400 pw.println("Database versions:"); 20401 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 20402 } 20403 } 20404 20405 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 20406 if (!checkin) { 20407 if (dumpState.onTitlePrinted()) 20408 pw.println(); 20409 pw.println("Verifiers:"); 20410 pw.print(" Required: "); 20411 pw.print(mRequiredVerifierPackage); 20412 pw.print(" (uid="); 20413 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 20414 UserHandle.USER_SYSTEM)); 20415 pw.println(")"); 20416 } else if (mRequiredVerifierPackage != null) { 20417 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 20418 pw.print(","); 20419 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 20420 UserHandle.USER_SYSTEM)); 20421 } 20422 } 20423 20424 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 20425 packageName == null) { 20426 if (mIntentFilterVerifierComponent != null) { 20427 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 20428 if (!checkin) { 20429 if (dumpState.onTitlePrinted()) 20430 pw.println(); 20431 pw.println("Intent Filter Verifier:"); 20432 pw.print(" Using: "); 20433 pw.print(verifierPackageName); 20434 pw.print(" (uid="); 20435 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 20436 UserHandle.USER_SYSTEM)); 20437 pw.println(")"); 20438 } else if (verifierPackageName != null) { 20439 pw.print("ifv,"); pw.print(verifierPackageName); 20440 pw.print(","); 20441 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 20442 UserHandle.USER_SYSTEM)); 20443 } 20444 } else { 20445 pw.println(); 20446 pw.println("No Intent Filter Verifier available!"); 20447 } 20448 } 20449 20450 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 20451 boolean printedHeader = false; 20452 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 20453 while (it.hasNext()) { 20454 String libName = it.next(); 20455 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName); 20456 if (versionedLib == null) { 20457 continue; 20458 } 20459 final int versionCount = versionedLib.size(); 20460 for (int i = 0; i < versionCount; i++) { 20461 SharedLibraryEntry libEntry = versionedLib.valueAt(i); 20462 if (!checkin) { 20463 if (!printedHeader) { 20464 if (dumpState.onTitlePrinted()) 20465 pw.println(); 20466 pw.println("Libraries:"); 20467 printedHeader = true; 20468 } 20469 pw.print(" "); 20470 } else { 20471 pw.print("lib,"); 20472 } 20473 pw.print(libEntry.info.getName()); 20474 if (libEntry.info.isStatic()) { 20475 pw.print(" version=" + libEntry.info.getVersion()); 20476 } 20477 if (!checkin) { 20478 pw.print(" -> "); 20479 } 20480 if (libEntry.path != null) { 20481 pw.print(" (jar) "); 20482 pw.print(libEntry.path); 20483 } else { 20484 pw.print(" (apk) "); 20485 pw.print(libEntry.apk); 20486 } 20487 pw.println(); 20488 } 20489 } 20490 } 20491 20492 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 20493 if (dumpState.onTitlePrinted()) 20494 pw.println(); 20495 if (!checkin) { 20496 pw.println("Features:"); 20497 } 20498 20499 synchronized (mAvailableFeatures) { 20500 for (FeatureInfo feat : mAvailableFeatures.values()) { 20501 if (checkin) { 20502 pw.print("feat,"); 20503 pw.print(feat.name); 20504 pw.print(","); 20505 pw.println(feat.version); 20506 } else { 20507 pw.print(" "); 20508 pw.print(feat.name); 20509 if (feat.version > 0) { 20510 pw.print(" version="); 20511 pw.print(feat.version); 20512 } 20513 pw.println(); 20514 } 20515 } 20516 } 20517 } 20518 20519 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 20520 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 20521 : "Activity Resolver Table:", " ", packageName, 20522 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20523 dumpState.setTitlePrinted(true); 20524 } 20525 } 20526 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 20527 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 20528 : "Receiver Resolver Table:", " ", packageName, 20529 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20530 dumpState.setTitlePrinted(true); 20531 } 20532 } 20533 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 20534 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 20535 : "Service Resolver Table:", " ", packageName, 20536 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20537 dumpState.setTitlePrinted(true); 20538 } 20539 } 20540 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 20541 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 20542 : "Provider Resolver Table:", " ", packageName, 20543 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20544 dumpState.setTitlePrinted(true); 20545 } 20546 } 20547 20548 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 20549 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 20550 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 20551 int user = mSettings.mPreferredActivities.keyAt(i); 20552 if (pir.dump(pw, 20553 dumpState.getTitlePrinted() 20554 ? "\nPreferred Activities User " + user + ":" 20555 : "Preferred Activities User " + user + ":", " ", 20556 packageName, true, false)) { 20557 dumpState.setTitlePrinted(true); 20558 } 20559 } 20560 } 20561 20562 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 20563 pw.flush(); 20564 FileOutputStream fout = new FileOutputStream(fd); 20565 BufferedOutputStream str = new BufferedOutputStream(fout); 20566 XmlSerializer serializer = new FastXmlSerializer(); 20567 try { 20568 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 20569 serializer.startDocument(null, true); 20570 serializer.setFeature( 20571 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 20572 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 20573 serializer.endDocument(); 20574 serializer.flush(); 20575 } catch (IllegalArgumentException e) { 20576 pw.println("Failed writing: " + e); 20577 } catch (IllegalStateException e) { 20578 pw.println("Failed writing: " + e); 20579 } catch (IOException e) { 20580 pw.println("Failed writing: " + e); 20581 } 20582 } 20583 20584 if (!checkin 20585 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 20586 && packageName == null) { 20587 pw.println(); 20588 int count = mSettings.mPackages.size(); 20589 if (count == 0) { 20590 pw.println("No applications!"); 20591 pw.println(); 20592 } else { 20593 final String prefix = " "; 20594 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 20595 if (allPackageSettings.size() == 0) { 20596 pw.println("No domain preferred apps!"); 20597 pw.println(); 20598 } else { 20599 pw.println("App verification status:"); 20600 pw.println(); 20601 count = 0; 20602 for (PackageSetting ps : allPackageSettings) { 20603 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 20604 if (ivi == null || ivi.getPackageName() == null) continue; 20605 pw.println(prefix + "Package: " + ivi.getPackageName()); 20606 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 20607 pw.println(prefix + "Status: " + ivi.getStatusString()); 20608 pw.println(); 20609 count++; 20610 } 20611 if (count == 0) { 20612 pw.println(prefix + "No app verification established."); 20613 pw.println(); 20614 } 20615 for (int userId : sUserManager.getUserIds()) { 20616 pw.println("App linkages for user " + userId + ":"); 20617 pw.println(); 20618 count = 0; 20619 for (PackageSetting ps : allPackageSettings) { 20620 final long status = ps.getDomainVerificationStatusForUser(userId); 20621 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED 20622 && !DEBUG_DOMAIN_VERIFICATION) { 20623 continue; 20624 } 20625 pw.println(prefix + "Package: " + ps.name); 20626 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 20627 String statusStr = IntentFilterVerificationInfo. 20628 getStatusStringFromValue(status); 20629 pw.println(prefix + "Status: " + statusStr); 20630 pw.println(); 20631 count++; 20632 } 20633 if (count == 0) { 20634 pw.println(prefix + "No configured app linkages."); 20635 pw.println(); 20636 } 20637 } 20638 } 20639 } 20640 } 20641 20642 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 20643 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 20644 if (packageName == null && permissionNames == null) { 20645 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 20646 if (iperm == 0) { 20647 if (dumpState.onTitlePrinted()) 20648 pw.println(); 20649 pw.println("AppOp Permissions:"); 20650 } 20651 pw.print(" AppOp Permission "); 20652 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 20653 pw.println(":"); 20654 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 20655 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 20656 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 20657 } 20658 } 20659 } 20660 } 20661 20662 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 20663 boolean printedSomething = false; 20664 for (PackageParser.Provider p : mProviders.mProviders.values()) { 20665 if (packageName != null && !packageName.equals(p.info.packageName)) { 20666 continue; 20667 } 20668 if (!printedSomething) { 20669 if (dumpState.onTitlePrinted()) 20670 pw.println(); 20671 pw.println("Registered ContentProviders:"); 20672 printedSomething = true; 20673 } 20674 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 20675 pw.print(" "); pw.println(p.toString()); 20676 } 20677 printedSomething = false; 20678 for (Map.Entry<String, PackageParser.Provider> entry : 20679 mProvidersByAuthority.entrySet()) { 20680 PackageParser.Provider p = entry.getValue(); 20681 if (packageName != null && !packageName.equals(p.info.packageName)) { 20682 continue; 20683 } 20684 if (!printedSomething) { 20685 if (dumpState.onTitlePrinted()) 20686 pw.println(); 20687 pw.println("ContentProvider Authorities:"); 20688 printedSomething = true; 20689 } 20690 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 20691 pw.print(" "); pw.println(p.toString()); 20692 if (p.info != null && p.info.applicationInfo != null) { 20693 final String appInfo = p.info.applicationInfo.toString(); 20694 pw.print(" applicationInfo="); pw.println(appInfo); 20695 } 20696 } 20697 } 20698 20699 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 20700 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 20701 } 20702 20703 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 20704 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 20705 } 20706 20707 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 20708 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 20709 } 20710 20711 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 20712 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 20713 } 20714 20715 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 20716 // XXX should handle packageName != null by dumping only install data that 20717 // the given package is involved with. 20718 if (dumpState.onTitlePrinted()) pw.println(); 20719 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 20720 } 20721 20722 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 20723 // XXX should handle packageName != null by dumping only install data that 20724 // the given package is involved with. 20725 if (dumpState.onTitlePrinted()) pw.println(); 20726 20727 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20728 ipw.println(); 20729 ipw.println("Frozen packages:"); 20730 ipw.increaseIndent(); 20731 if (mFrozenPackages.size() == 0) { 20732 ipw.println("(none)"); 20733 } else { 20734 for (int i = 0; i < mFrozenPackages.size(); i++) { 20735 ipw.println(mFrozenPackages.valueAt(i)); 20736 } 20737 } 20738 ipw.decreaseIndent(); 20739 } 20740 20741 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 20742 if (dumpState.onTitlePrinted()) pw.println(); 20743 dumpDexoptStateLPr(pw, packageName); 20744 } 20745 20746 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 20747 if (dumpState.onTitlePrinted()) pw.println(); 20748 dumpCompilerStatsLPr(pw, packageName); 20749 } 20750 20751 if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) { 20752 if (dumpState.onTitlePrinted()) pw.println(); 20753 dumpEnabledOverlaysLPr(pw); 20754 } 20755 20756 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 20757 if (dumpState.onTitlePrinted()) pw.println(); 20758 mSettings.dumpReadMessagesLPr(pw, dumpState); 20759 20760 pw.println(); 20761 pw.println("Package warning messages:"); 20762 BufferedReader in = null; 20763 String line = null; 20764 try { 20765 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20766 while ((line = in.readLine()) != null) { 20767 if (line.contains("ignored: updated version")) continue; 20768 pw.println(line); 20769 } 20770 } catch (IOException ignored) { 20771 } finally { 20772 IoUtils.closeQuietly(in); 20773 } 20774 } 20775 20776 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 20777 BufferedReader in = null; 20778 String line = null; 20779 try { 20780 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20781 while ((line = in.readLine()) != null) { 20782 if (line.contains("ignored: updated version")) continue; 20783 pw.print("msg,"); 20784 pw.println(line); 20785 } 20786 } catch (IOException ignored) { 20787 } finally { 20788 IoUtils.closeQuietly(in); 20789 } 20790 } 20791 } 20792 } 20793 20794 private void dumpProto(FileDescriptor fd) { 20795 final ProtoOutputStream proto = new ProtoOutputStream(fd); 20796 20797 synchronized (mPackages) { 20798 final long requiredVerifierPackageToken = 20799 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE); 20800 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage); 20801 proto.write( 20802 PackageServiceDumpProto.PackageShortProto.UID, 20803 getPackageUid( 20804 mRequiredVerifierPackage, 20805 MATCH_DEBUG_TRIAGED_MISSING, 20806 UserHandle.USER_SYSTEM)); 20807 proto.end(requiredVerifierPackageToken); 20808 20809 if (mIntentFilterVerifierComponent != null) { 20810 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 20811 final long verifierPackageToken = 20812 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE); 20813 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName); 20814 proto.write( 20815 PackageServiceDumpProto.PackageShortProto.UID, 20816 getPackageUid( 20817 verifierPackageName, 20818 MATCH_DEBUG_TRIAGED_MISSING, 20819 UserHandle.USER_SYSTEM)); 20820 proto.end(verifierPackageToken); 20821 } 20822 20823 dumpSharedLibrariesProto(proto); 20824 dumpFeaturesProto(proto); 20825 mSettings.dumpPackagesProto(proto); 20826 mSettings.dumpSharedUsersProto(proto); 20827 dumpMessagesProto(proto); 20828 } 20829 proto.flush(); 20830 } 20831 20832 private void dumpMessagesProto(ProtoOutputStream proto) { 20833 BufferedReader in = null; 20834 String line = null; 20835 try { 20836 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20837 while ((line = in.readLine()) != null) { 20838 if (line.contains("ignored: updated version")) continue; 20839 proto.write(PackageServiceDumpProto.MESSAGES, line); 20840 } 20841 } catch (IOException ignored) { 20842 } finally { 20843 IoUtils.closeQuietly(in); 20844 } 20845 } 20846 20847 private void dumpFeaturesProto(ProtoOutputStream proto) { 20848 synchronized (mAvailableFeatures) { 20849 final int count = mAvailableFeatures.size(); 20850 for (int i = 0; i < count; i++) { 20851 final FeatureInfo feat = mAvailableFeatures.valueAt(i); 20852 final long featureToken = proto.start(PackageServiceDumpProto.FEATURES); 20853 proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name); 20854 proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version); 20855 proto.end(featureToken); 20856 } 20857 } 20858 } 20859 20860 private void dumpSharedLibrariesProto(ProtoOutputStream proto) { 20861 final int count = mSharedLibraries.size(); 20862 for (int i = 0; i < count; i++) { 20863 final String libName = mSharedLibraries.keyAt(i); 20864 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName); 20865 if (versionedLib == null) { 20866 continue; 20867 } 20868 final int versionCount = versionedLib.size(); 20869 for (int j = 0; j < versionCount; j++) { 20870 final SharedLibraryEntry libEntry = versionedLib.valueAt(j); 20871 final long sharedLibraryToken = 20872 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES); 20873 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName()); 20874 final boolean isJar = (libEntry.path != null); 20875 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar); 20876 if (isJar) { 20877 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path); 20878 } else { 20879 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk); 20880 } 20881 proto.end(sharedLibraryToken); 20882 } 20883 } 20884 } 20885 20886 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 20887 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20888 ipw.println(); 20889 ipw.println("Dexopt state:"); 20890 ipw.increaseIndent(); 20891 Collection<PackageParser.Package> packages = null; 20892 if (packageName != null) { 20893 PackageParser.Package targetPackage = mPackages.get(packageName); 20894 if (targetPackage != null) { 20895 packages = Collections.singletonList(targetPackage); 20896 } else { 20897 ipw.println("Unable to find package: " + packageName); 20898 return; 20899 } 20900 } else { 20901 packages = mPackages.values(); 20902 } 20903 20904 for (PackageParser.Package pkg : packages) { 20905 ipw.println("[" + pkg.packageName + "]"); 20906 ipw.increaseIndent(); 20907 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 20908 ipw.decreaseIndent(); 20909 } 20910 } 20911 20912 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 20913 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20914 ipw.println(); 20915 ipw.println("Compiler stats:"); 20916 ipw.increaseIndent(); 20917 Collection<PackageParser.Package> packages = null; 20918 if (packageName != null) { 20919 PackageParser.Package targetPackage = mPackages.get(packageName); 20920 if (targetPackage != null) { 20921 packages = Collections.singletonList(targetPackage); 20922 } else { 20923 ipw.println("Unable to find package: " + packageName); 20924 return; 20925 } 20926 } else { 20927 packages = mPackages.values(); 20928 } 20929 20930 for (PackageParser.Package pkg : packages) { 20931 ipw.println("[" + pkg.packageName + "]"); 20932 ipw.increaseIndent(); 20933 20934 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 20935 if (stats == null) { 20936 ipw.println("(No recorded stats)"); 20937 } else { 20938 stats.dump(ipw); 20939 } 20940 ipw.decreaseIndent(); 20941 } 20942 } 20943 20944 private void dumpEnabledOverlaysLPr(PrintWriter pw) { 20945 pw.println("Enabled overlay paths:"); 20946 final int N = mEnabledOverlayPaths.size(); 20947 for (int i = 0; i < N; i++) { 20948 final int userId = mEnabledOverlayPaths.keyAt(i); 20949 pw.println(String.format(" User %d:", userId)); 20950 final ArrayMap<String, ArrayList<String>> userSpecificOverlays = 20951 mEnabledOverlayPaths.valueAt(i); 20952 final int M = userSpecificOverlays.size(); 20953 for (int j = 0; j < M; j++) { 20954 final String targetPackageName = userSpecificOverlays.keyAt(j); 20955 final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j); 20956 pw.println(String.format(" %s: %s", targetPackageName, overlayPackagePaths)); 20957 } 20958 } 20959 } 20960 20961 private String dumpDomainString(String packageName) { 20962 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 20963 .getList(); 20964 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 20965 20966 ArraySet<String> result = new ArraySet<>(); 20967 if (iviList.size() > 0) { 20968 for (IntentFilterVerificationInfo ivi : iviList) { 20969 for (String host : ivi.getDomains()) { 20970 result.add(host); 20971 } 20972 } 20973 } 20974 if (filters != null && filters.size() > 0) { 20975 for (IntentFilter filter : filters) { 20976 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 20977 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 20978 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 20979 result.addAll(filter.getHostsList()); 20980 } 20981 } 20982 } 20983 20984 StringBuilder sb = new StringBuilder(result.size() * 16); 20985 for (String domain : result) { 20986 if (sb.length() > 0) sb.append(" "); 20987 sb.append(domain); 20988 } 20989 return sb.toString(); 20990 } 20991 20992 // ------- apps on sdcard specific code ------- 20993 static final boolean DEBUG_SD_INSTALL = false; 20994 20995 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 20996 20997 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 20998 20999 private boolean mMediaMounted = false; 21000 21001 static String getEncryptKey() { 21002 try { 21003 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 21004 SD_ENCRYPTION_KEYSTORE_NAME); 21005 if (sdEncKey == null) { 21006 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 21007 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 21008 if (sdEncKey == null) { 21009 Slog.e(TAG, "Failed to create encryption keys"); 21010 return null; 21011 } 21012 } 21013 return sdEncKey; 21014 } catch (NoSuchAlgorithmException nsae) { 21015 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 21016 return null; 21017 } catch (IOException ioe) { 21018 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 21019 return null; 21020 } 21021 } 21022 21023 /* 21024 * Update media status on PackageManager. 21025 */ 21026 @Override 21027 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 21028 int callingUid = Binder.getCallingUid(); 21029 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 21030 throw new SecurityException("Media status can only be updated by the system"); 21031 } 21032 // reader; this apparently protects mMediaMounted, but should probably 21033 // be a different lock in that case. 21034 synchronized (mPackages) { 21035 Log.i(TAG, "Updating external media status from " 21036 + (mMediaMounted ? "mounted" : "unmounted") + " to " 21037 + (mediaStatus ? "mounted" : "unmounted")); 21038 if (DEBUG_SD_INSTALL) 21039 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 21040 + ", mMediaMounted=" + mMediaMounted); 21041 if (mediaStatus == mMediaMounted) { 21042 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 21043 : 0, -1); 21044 mHandler.sendMessage(msg); 21045 return; 21046 } 21047 mMediaMounted = mediaStatus; 21048 } 21049 // Queue up an async operation since the package installation may take a 21050 // little while. 21051 mHandler.post(new Runnable() { 21052 public void run() { 21053 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 21054 } 21055 }); 21056 } 21057 21058 /** 21059 * Called by StorageManagerService when the initial ASECs to scan are available. 21060 * Should block until all the ASEC containers are finished being scanned. 21061 */ 21062 public void scanAvailableAsecs() { 21063 updateExternalMediaStatusInner(true, false, false); 21064 } 21065 21066 /* 21067 * Collect information of applications on external media, map them against 21068 * existing containers and update information based on current mount status. 21069 * Please note that we always have to report status if reportStatus has been 21070 * set to true especially when unloading packages. 21071 */ 21072 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 21073 boolean externalStorage) { 21074 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 21075 int[] uidArr = EmptyArray.INT; 21076 21077 final String[] list = PackageHelper.getSecureContainerList(); 21078 if (ArrayUtils.isEmpty(list)) { 21079 Log.i(TAG, "No secure containers found"); 21080 } else { 21081 // Process list of secure containers and categorize them 21082 // as active or stale based on their package internal state. 21083 21084 // reader 21085 synchronized (mPackages) { 21086 for (String cid : list) { 21087 // Leave stages untouched for now; installer service owns them 21088 if (PackageInstallerService.isStageName(cid)) continue; 21089 21090 if (DEBUG_SD_INSTALL) 21091 Log.i(TAG, "Processing container " + cid); 21092 String pkgName = getAsecPackageName(cid); 21093 if (pkgName == null) { 21094 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 21095 continue; 21096 } 21097 if (DEBUG_SD_INSTALL) 21098 Log.i(TAG, "Looking for pkg : " + pkgName); 21099 21100 final PackageSetting ps = mSettings.mPackages.get(pkgName); 21101 if (ps == null) { 21102 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 21103 continue; 21104 } 21105 21106 /* 21107 * Skip packages that are not external if we're unmounting 21108 * external storage. 21109 */ 21110 if (externalStorage && !isMounted && !isExternal(ps)) { 21111 continue; 21112 } 21113 21114 final AsecInstallArgs args = new AsecInstallArgs(cid, 21115 getAppDexInstructionSets(ps), ps.isForwardLocked()); 21116 // The package status is changed only if the code path 21117 // matches between settings and the container id. 21118 if (ps.codePathString != null 21119 && ps.codePathString.startsWith(args.getCodePath())) { 21120 if (DEBUG_SD_INSTALL) { 21121 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 21122 + " at code path: " + ps.codePathString); 21123 } 21124 21125 // We do have a valid package installed on sdcard 21126 processCids.put(args, ps.codePathString); 21127 final int uid = ps.appId; 21128 if (uid != -1) { 21129 uidArr = ArrayUtils.appendInt(uidArr, uid); 21130 } 21131 } else { 21132 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 21133 + ps.codePathString); 21134 } 21135 } 21136 } 21137 21138 Arrays.sort(uidArr); 21139 } 21140 21141 // Process packages with valid entries. 21142 if (isMounted) { 21143 if (DEBUG_SD_INSTALL) 21144 Log.i(TAG, "Loading packages"); 21145 loadMediaPackages(processCids, uidArr, externalStorage); 21146 startCleaningPackages(); 21147 mInstallerService.onSecureContainersAvailable(); 21148 } else { 21149 if (DEBUG_SD_INSTALL) 21150 Log.i(TAG, "Unloading packages"); 21151 unloadMediaPackages(processCids, uidArr, reportStatus); 21152 } 21153 } 21154 21155 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21156 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 21157 final int size = infos.size(); 21158 final String[] packageNames = new String[size]; 21159 final int[] packageUids = new int[size]; 21160 for (int i = 0; i < size; i++) { 21161 final ApplicationInfo info = infos.get(i); 21162 packageNames[i] = info.packageName; 21163 packageUids[i] = info.uid; 21164 } 21165 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 21166 finishedReceiver); 21167 } 21168 21169 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21170 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 21171 sendResourcesChangedBroadcast(mediaStatus, replacing, 21172 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 21173 } 21174 21175 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21176 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 21177 int size = pkgList.length; 21178 if (size > 0) { 21179 // Send broadcasts here 21180 Bundle extras = new Bundle(); 21181 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 21182 if (uidArr != null) { 21183 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 21184 } 21185 if (replacing) { 21186 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 21187 } 21188 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 21189 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 21190 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 21191 } 21192 } 21193 21194 /* 21195 * Look at potentially valid container ids from processCids If package 21196 * information doesn't match the one on record or package scanning fails, 21197 * the cid is added to list of removeCids. We currently don't delete stale 21198 * containers. 21199 */ 21200 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 21201 boolean externalStorage) { 21202 ArrayList<String> pkgList = new ArrayList<String>(); 21203 Set<AsecInstallArgs> keys = processCids.keySet(); 21204 21205 for (AsecInstallArgs args : keys) { 21206 String codePath = processCids.get(args); 21207 if (DEBUG_SD_INSTALL) 21208 Log.i(TAG, "Loading container : " + args.cid); 21209 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 21210 try { 21211 // Make sure there are no container errors first. 21212 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 21213 Slog.e(TAG, "Failed to mount cid : " + args.cid 21214 + " when installing from sdcard"); 21215 continue; 21216 } 21217 // Check code path here. 21218 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 21219 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 21220 + " does not match one in settings " + codePath); 21221 continue; 21222 } 21223 // Parse package 21224 int parseFlags = mDefParseFlags; 21225 if (args.isExternalAsec()) { 21226 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 21227 } 21228 if (args.isFwdLocked()) { 21229 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 21230 } 21231 21232 synchronized (mInstallLock) { 21233 PackageParser.Package pkg = null; 21234 try { 21235 // Sadly we don't know the package name yet to freeze it 21236 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 21237 SCAN_IGNORE_FROZEN, 0, null); 21238 } catch (PackageManagerException e) { 21239 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 21240 } 21241 // Scan the package 21242 if (pkg != null) { 21243 /* 21244 * TODO why is the lock being held? doPostInstall is 21245 * called in other places without the lock. This needs 21246 * to be straightened out. 21247 */ 21248 // writer 21249 synchronized (mPackages) { 21250 retCode = PackageManager.INSTALL_SUCCEEDED; 21251 pkgList.add(pkg.packageName); 21252 // Post process args 21253 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 21254 pkg.applicationInfo.uid); 21255 } 21256 } else { 21257 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 21258 } 21259 } 21260 21261 } finally { 21262 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 21263 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 21264 } 21265 } 21266 } 21267 // writer 21268 synchronized (mPackages) { 21269 // If the platform SDK has changed since the last time we booted, 21270 // we need to re-grant app permission to catch any new ones that 21271 // appear. This is really a hack, and means that apps can in some 21272 // cases get permissions that the user didn't initially explicitly 21273 // allow... it would be nice to have some better way to handle 21274 // this situation. 21275 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 21276 : mSettings.getInternalVersion(); 21277 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 21278 : StorageManager.UUID_PRIVATE_INTERNAL; 21279 21280 int updateFlags = UPDATE_PERMISSIONS_ALL; 21281 if (ver.sdkVersion != mSdkVersion) { 21282 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 21283 + mSdkVersion + "; regranting permissions for external"); 21284 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 21285 } 21286 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 21287 21288 // Yay, everything is now upgraded 21289 ver.forceCurrent(); 21290 21291 // can downgrade to reader 21292 // Persist settings 21293 mSettings.writeLPr(); 21294 } 21295 // Send a broadcast to let everyone know we are done processing 21296 if (pkgList.size() > 0) { 21297 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 21298 } 21299 } 21300 21301 /* 21302 * Utility method to unload a list of specified containers 21303 */ 21304 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 21305 // Just unmount all valid containers. 21306 for (AsecInstallArgs arg : cidArgs) { 21307 synchronized (mInstallLock) { 21308 arg.doPostDeleteLI(false); 21309 } 21310 } 21311 } 21312 21313 /* 21314 * Unload packages mounted on external media. This involves deleting package 21315 * data from internal structures, sending broadcasts about disabled packages, 21316 * gc'ing to free up references, unmounting all secure containers 21317 * corresponding to packages on external media, and posting a 21318 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 21319 * that we always have to post this message if status has been requested no 21320 * matter what. 21321 */ 21322 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 21323 final boolean reportStatus) { 21324 if (DEBUG_SD_INSTALL) 21325 Log.i(TAG, "unloading media packages"); 21326 ArrayList<String> pkgList = new ArrayList<String>(); 21327 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 21328 final Set<AsecInstallArgs> keys = processCids.keySet(); 21329 for (AsecInstallArgs args : keys) { 21330 String pkgName = args.getPackageName(); 21331 if (DEBUG_SD_INSTALL) 21332 Log.i(TAG, "Trying to unload pkg : " + pkgName); 21333 // Delete package internally 21334 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 21335 synchronized (mInstallLock) { 21336 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 21337 final boolean res; 21338 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 21339 "unloadMediaPackages")) { 21340 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 21341 null); 21342 } 21343 if (res) { 21344 pkgList.add(pkgName); 21345 } else { 21346 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 21347 failedList.add(args); 21348 } 21349 } 21350 } 21351 21352 // reader 21353 synchronized (mPackages) { 21354 // We didn't update the settings after removing each package; 21355 // write them now for all packages. 21356 mSettings.writeLPr(); 21357 } 21358 21359 // We have to absolutely send UPDATED_MEDIA_STATUS only 21360 // after confirming that all the receivers processed the ordered 21361 // broadcast when packages get disabled, force a gc to clean things up. 21362 // and unload all the containers. 21363 if (pkgList.size() > 0) { 21364 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 21365 new IIntentReceiver.Stub() { 21366 public void performReceive(Intent intent, int resultCode, String data, 21367 Bundle extras, boolean ordered, boolean sticky, 21368 int sendingUser) throws RemoteException { 21369 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 21370 reportStatus ? 1 : 0, 1, keys); 21371 mHandler.sendMessage(msg); 21372 } 21373 }); 21374 } else { 21375 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 21376 keys); 21377 mHandler.sendMessage(msg); 21378 } 21379 } 21380 21381 private void loadPrivatePackages(final VolumeInfo vol) { 21382 mHandler.post(new Runnable() { 21383 @Override 21384 public void run() { 21385 loadPrivatePackagesInner(vol); 21386 } 21387 }); 21388 } 21389 21390 private void loadPrivatePackagesInner(VolumeInfo vol) { 21391 final String volumeUuid = vol.fsUuid; 21392 if (TextUtils.isEmpty(volumeUuid)) { 21393 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 21394 return; 21395 } 21396 21397 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 21398 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 21399 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 21400 21401 final VersionInfo ver; 21402 final List<PackageSetting> packages; 21403 synchronized (mPackages) { 21404 ver = mSettings.findOrCreateVersion(volumeUuid); 21405 packages = mSettings.getVolumePackagesLPr(volumeUuid); 21406 } 21407 21408 for (PackageSetting ps : packages) { 21409 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 21410 synchronized (mInstallLock) { 21411 final PackageParser.Package pkg; 21412 try { 21413 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 21414 loaded.add(pkg.applicationInfo); 21415 21416 } catch (PackageManagerException e) { 21417 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 21418 } 21419 21420 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 21421 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 21422 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 21423 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 21424 } 21425 } 21426 } 21427 21428 // Reconcile app data for all started/unlocked users 21429 final StorageManager sm = mContext.getSystemService(StorageManager.class); 21430 final UserManager um = mContext.getSystemService(UserManager.class); 21431 UserManagerInternal umInternal = getUserManagerInternal(); 21432 for (UserInfo user : um.getUsers()) { 21433 final int flags; 21434 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 21435 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 21436 } else if (umInternal.isUserRunning(user.id)) { 21437 flags = StorageManager.FLAG_STORAGE_DE; 21438 } else { 21439 continue; 21440 } 21441 21442 try { 21443 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 21444 synchronized (mInstallLock) { 21445 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */); 21446 } 21447 } catch (IllegalStateException e) { 21448 // Device was probably ejected, and we'll process that event momentarily 21449 Slog.w(TAG, "Failed to prepare storage: " + e); 21450 } 21451 } 21452 21453 synchronized (mPackages) { 21454 int updateFlags = UPDATE_PERMISSIONS_ALL; 21455 if (ver.sdkVersion != mSdkVersion) { 21456 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 21457 + mSdkVersion + "; regranting permissions for " + volumeUuid); 21458 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 21459 } 21460 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 21461 21462 // Yay, everything is now upgraded 21463 ver.forceCurrent(); 21464 21465 mSettings.writeLPr(); 21466 } 21467 21468 for (PackageFreezer freezer : freezers) { 21469 freezer.close(); 21470 } 21471 21472 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 21473 sendResourcesChangedBroadcast(true, false, loaded, null); 21474 } 21475 21476 private void unloadPrivatePackages(final VolumeInfo vol) { 21477 mHandler.post(new Runnable() { 21478 @Override 21479 public void run() { 21480 unloadPrivatePackagesInner(vol); 21481 } 21482 }); 21483 } 21484 21485 private void unloadPrivatePackagesInner(VolumeInfo vol) { 21486 final String volumeUuid = vol.fsUuid; 21487 if (TextUtils.isEmpty(volumeUuid)) { 21488 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 21489 return; 21490 } 21491 21492 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 21493 synchronized (mInstallLock) { 21494 synchronized (mPackages) { 21495 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 21496 for (PackageSetting ps : packages) { 21497 if (ps.pkg == null) continue; 21498 21499 final ApplicationInfo info = ps.pkg.applicationInfo; 21500 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 21501 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 21502 21503 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 21504 "unloadPrivatePackagesInner")) { 21505 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 21506 false, null)) { 21507 unloaded.add(info); 21508 } else { 21509 Slog.w(TAG, "Failed to unload " + ps.codePath); 21510 } 21511 } 21512 21513 // Try very hard to release any references to this package 21514 // so we don't risk the system server being killed due to 21515 // open FDs 21516 AttributeCache.instance().removePackage(ps.name); 21517 } 21518 21519 mSettings.writeLPr(); 21520 } 21521 } 21522 21523 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 21524 sendResourcesChangedBroadcast(false, false, unloaded, null); 21525 21526 // Try very hard to release any references to this path so we don't risk 21527 // the system server being killed due to open FDs 21528 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 21529 21530 for (int i = 0; i < 3; i++) { 21531 System.gc(); 21532 System.runFinalization(); 21533 } 21534 } 21535 21536 private void assertPackageKnown(String volumeUuid, String packageName) 21537 throws PackageManagerException { 21538 synchronized (mPackages) { 21539 // Normalize package name to handle renamed packages 21540 packageName = normalizePackageNameLPr(packageName); 21541 21542 final PackageSetting ps = mSettings.mPackages.get(packageName); 21543 if (ps == null) { 21544 throw new PackageManagerException("Package " + packageName + " is unknown"); 21545 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 21546 throw new PackageManagerException( 21547 "Package " + packageName + " found on unknown volume " + volumeUuid 21548 + "; expected volume " + ps.volumeUuid); 21549 } 21550 } 21551 } 21552 21553 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 21554 throws PackageManagerException { 21555 synchronized (mPackages) { 21556 // Normalize package name to handle renamed packages 21557 packageName = normalizePackageNameLPr(packageName); 21558 21559 final PackageSetting ps = mSettings.mPackages.get(packageName); 21560 if (ps == null) { 21561 throw new PackageManagerException("Package " + packageName + " is unknown"); 21562 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 21563 throw new PackageManagerException( 21564 "Package " + packageName + " found on unknown volume " + volumeUuid 21565 + "; expected volume " + ps.volumeUuid); 21566 } else if (!ps.getInstalled(userId)) { 21567 throw new PackageManagerException( 21568 "Package " + packageName + " not installed for user " + userId); 21569 } 21570 } 21571 } 21572 21573 private List<String> collectAbsoluteCodePaths() { 21574 synchronized (mPackages) { 21575 List<String> codePaths = new ArrayList<>(); 21576 final int packageCount = mSettings.mPackages.size(); 21577 for (int i = 0; i < packageCount; i++) { 21578 final PackageSetting ps = mSettings.mPackages.valueAt(i); 21579 codePaths.add(ps.codePath.getAbsolutePath()); 21580 } 21581 return codePaths; 21582 } 21583 } 21584 21585 /** 21586 * Examine all apps present on given mounted volume, and destroy apps that 21587 * aren't expected, either due to uninstallation or reinstallation on 21588 * another volume. 21589 */ 21590 private void reconcileApps(String volumeUuid) { 21591 List<String> absoluteCodePaths = collectAbsoluteCodePaths(); 21592 List<File> filesToDelete = null; 21593 21594 final File[] files = FileUtils.listFilesOrEmpty( 21595 Environment.getDataAppDirectory(volumeUuid)); 21596 for (File file : files) { 21597 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 21598 && !PackageInstallerService.isStageName(file.getName()); 21599 if (!isPackage) { 21600 // Ignore entries which are not packages 21601 continue; 21602 } 21603 21604 String absolutePath = file.getAbsolutePath(); 21605 21606 boolean pathValid = false; 21607 final int absoluteCodePathCount = absoluteCodePaths.size(); 21608 for (int i = 0; i < absoluteCodePathCount; i++) { 21609 String absoluteCodePath = absoluteCodePaths.get(i); 21610 if (absolutePath.startsWith(absoluteCodePath)) { 21611 pathValid = true; 21612 break; 21613 } 21614 } 21615 21616 if (!pathValid) { 21617 if (filesToDelete == null) { 21618 filesToDelete = new ArrayList<>(); 21619 } 21620 filesToDelete.add(file); 21621 } 21622 } 21623 21624 if (filesToDelete != null) { 21625 final int fileToDeleteCount = filesToDelete.size(); 21626 for (int i = 0; i < fileToDeleteCount; i++) { 21627 File fileToDelete = filesToDelete.get(i); 21628 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete); 21629 synchronized (mInstallLock) { 21630 removeCodePathLI(fileToDelete); 21631 } 21632 } 21633 } 21634 } 21635 21636 /** 21637 * Reconcile all app data for the given user. 21638 * <p> 21639 * Verifies that directories exist and that ownership and labeling is 21640 * correct for all installed apps on all mounted volumes. 21641 */ 21642 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) { 21643 final StorageManager storage = mContext.getSystemService(StorageManager.class); 21644 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 21645 final String volumeUuid = vol.getFsUuid(); 21646 synchronized (mInstallLock) { 21647 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData); 21648 } 21649 } 21650 } 21651 21652 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags, 21653 boolean migrateAppData) { 21654 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */); 21655 } 21656 21657 /** 21658 * Reconcile all app data on given mounted volume. 21659 * <p> 21660 * Destroys app data that isn't expected, either due to uninstallation or 21661 * reinstallation on another volume. 21662 * <p> 21663 * Verifies that directories exist and that ownership and labeling is 21664 * correct for all installed apps. 21665 * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true) 21666 */ 21667 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags, 21668 boolean migrateAppData, boolean onlyCoreApps) { 21669 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 21670 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData); 21671 List<String> result = onlyCoreApps ? new ArrayList<>() : null; 21672 21673 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 21674 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 21675 21676 // First look for stale data that doesn't belong, and check if things 21677 // have changed since we did our last restorecon 21678 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 21679 if (StorageManager.isFileEncryptedNativeOrEmulated() 21680 && !StorageManager.isUserKeyUnlocked(userId)) { 21681 throw new RuntimeException( 21682 "Yikes, someone asked us to reconcile CE storage while " + userId 21683 + " was still locked; this would have caused massive data loss!"); 21684 } 21685 21686 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 21687 for (File file : files) { 21688 final String packageName = file.getName(); 21689 try { 21690 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 21691 } catch (PackageManagerException e) { 21692 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 21693 try { 21694 mInstaller.destroyAppData(volumeUuid, packageName, userId, 21695 StorageManager.FLAG_STORAGE_CE, 0); 21696 } catch (InstallerException e2) { 21697 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 21698 } 21699 } 21700 } 21701 } 21702 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 21703 final File[] files = FileUtils.listFilesOrEmpty(deDir); 21704 for (File file : files) { 21705 final String packageName = file.getName(); 21706 try { 21707 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 21708 } catch (PackageManagerException e) { 21709 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 21710 try { 21711 mInstaller.destroyAppData(volumeUuid, packageName, userId, 21712 StorageManager.FLAG_STORAGE_DE, 0); 21713 } catch (InstallerException e2) { 21714 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 21715 } 21716 } 21717 } 21718 } 21719 21720 // Ensure that data directories are ready to roll for all packages 21721 // installed for this volume and user 21722 final List<PackageSetting> packages; 21723 synchronized (mPackages) { 21724 packages = mSettings.getVolumePackagesLPr(volumeUuid); 21725 } 21726 int preparedCount = 0; 21727 for (PackageSetting ps : packages) { 21728 final String packageName = ps.name; 21729 if (ps.pkg == null) { 21730 Slog.w(TAG, "Odd, missing scanned package " + packageName); 21731 // TODO: might be due to legacy ASEC apps; we should circle back 21732 // and reconcile again once they're scanned 21733 continue; 21734 } 21735 // Skip non-core apps if requested 21736 if (onlyCoreApps && !ps.pkg.coreApp) { 21737 result.add(packageName); 21738 continue; 21739 } 21740 21741 if (ps.getInstalled(userId)) { 21742 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData); 21743 preparedCount++; 21744 } 21745 } 21746 21747 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); 21748 return result; 21749 } 21750 21751 /** 21752 * Prepare app data for the given app just after it was installed or 21753 * upgraded. This method carefully only touches users that it's installed 21754 * for, and it forces a restorecon to handle any seinfo changes. 21755 * <p> 21756 * Verifies that directories exist and that ownership and labeling is 21757 * correct for all installed apps. If there is an ownership mismatch, it 21758 * will try recovering system apps by wiping data; third-party app data is 21759 * left intact. 21760 * <p> 21761 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 21762 */ 21763 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 21764 final PackageSetting ps; 21765 synchronized (mPackages) { 21766 ps = mSettings.mPackages.get(pkg.packageName); 21767 mSettings.writeKernelMappingLPr(ps); 21768 } 21769 21770 final UserManager um = mContext.getSystemService(UserManager.class); 21771 UserManagerInternal umInternal = getUserManagerInternal(); 21772 for (UserInfo user : um.getUsers()) { 21773 final int flags; 21774 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 21775 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 21776 } else if (umInternal.isUserRunning(user.id)) { 21777 flags = StorageManager.FLAG_STORAGE_DE; 21778 } else { 21779 continue; 21780 } 21781 21782 if (ps.getInstalled(user.id)) { 21783 // TODO: when user data is locked, mark that we're still dirty 21784 prepareAppDataLIF(pkg, user.id, flags); 21785 } 21786 } 21787 } 21788 21789 /** 21790 * Prepare app data for the given app. 21791 * <p> 21792 * Verifies that directories exist and that ownership and labeling is 21793 * correct for all installed apps. If there is an ownership mismatch, this 21794 * will try recovering system apps by wiping data; third-party app data is 21795 * left intact. 21796 */ 21797 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 21798 if (pkg == null) { 21799 Slog.wtf(TAG, "Package was null!", new Throwable()); 21800 return; 21801 } 21802 prepareAppDataLeafLIF(pkg, userId, flags); 21803 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 21804 for (int i = 0; i < childCount; i++) { 21805 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 21806 } 21807 } 21808 21809 private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags, 21810 boolean maybeMigrateAppData) { 21811 prepareAppDataLIF(pkg, userId, flags); 21812 21813 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) { 21814 // We may have just shuffled around app data directories, so 21815 // prepare them one more time 21816 prepareAppDataLIF(pkg, userId, flags); 21817 } 21818 } 21819 21820 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 21821 if (DEBUG_APP_DATA) { 21822 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 21823 + Integer.toHexString(flags)); 21824 } 21825 21826 final String volumeUuid = pkg.volumeUuid; 21827 final String packageName = pkg.packageName; 21828 final ApplicationInfo app = pkg.applicationInfo; 21829 final int appId = UserHandle.getAppId(app.uid); 21830 21831 Preconditions.checkNotNull(app.seInfo); 21832 21833 long ceDataInode = -1; 21834 try { 21835 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 21836 appId, app.seInfo, app.targetSdkVersion); 21837 } catch (InstallerException e) { 21838 if (app.isSystemApp()) { 21839 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 21840 + ", but trying to recover: " + e); 21841 destroyAppDataLeafLIF(pkg, userId, flags); 21842 try { 21843 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 21844 appId, app.seInfo, app.targetSdkVersion); 21845 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 21846 } catch (InstallerException e2) { 21847 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 21848 } 21849 } else { 21850 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 21851 } 21852 } 21853 21854 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { 21855 // TODO: mark this structure as dirty so we persist it! 21856 synchronized (mPackages) { 21857 final PackageSetting ps = mSettings.mPackages.get(packageName); 21858 if (ps != null) { 21859 ps.setCeDataInode(ceDataInode, userId); 21860 } 21861 } 21862 } 21863 21864 prepareAppDataContentsLeafLIF(pkg, userId, flags); 21865 } 21866 21867 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 21868 if (pkg == null) { 21869 Slog.wtf(TAG, "Package was null!", new Throwable()); 21870 return; 21871 } 21872 prepareAppDataContentsLeafLIF(pkg, userId, flags); 21873 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 21874 for (int i = 0; i < childCount; i++) { 21875 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 21876 } 21877 } 21878 21879 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 21880 final String volumeUuid = pkg.volumeUuid; 21881 final String packageName = pkg.packageName; 21882 final ApplicationInfo app = pkg.applicationInfo; 21883 21884 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 21885 // Create a native library symlink only if we have native libraries 21886 // and if the native libraries are 32 bit libraries. We do not provide 21887 // this symlink for 64 bit libraries. 21888 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 21889 final String nativeLibPath = app.nativeLibraryDir; 21890 try { 21891 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 21892 nativeLibPath, userId); 21893 } catch (InstallerException e) { 21894 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 21895 } 21896 } 21897 } 21898 } 21899 21900 /** 21901 * For system apps on non-FBE devices, this method migrates any existing 21902 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 21903 * requested by the app. 21904 */ 21905 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 21906 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 21907 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 21908 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 21909 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 21910 try { 21911 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 21912 storageTarget); 21913 } catch (InstallerException e) { 21914 logCriticalInfo(Log.WARN, 21915 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 21916 } 21917 return true; 21918 } else { 21919 return false; 21920 } 21921 } 21922 21923 public PackageFreezer freezePackage(String packageName, String killReason) { 21924 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 21925 } 21926 21927 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 21928 return new PackageFreezer(packageName, userId, killReason); 21929 } 21930 21931 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 21932 String killReason) { 21933 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 21934 } 21935 21936 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 21937 String killReason) { 21938 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 21939 return new PackageFreezer(); 21940 } else { 21941 return freezePackage(packageName, userId, killReason); 21942 } 21943 } 21944 21945 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 21946 String killReason) { 21947 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 21948 } 21949 21950 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 21951 String killReason) { 21952 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 21953 return new PackageFreezer(); 21954 } else { 21955 return freezePackage(packageName, userId, killReason); 21956 } 21957 } 21958 21959 /** 21960 * Class that freezes and kills the given package upon creation, and 21961 * unfreezes it upon closing. This is typically used when doing surgery on 21962 * app code/data to prevent the app from running while you're working. 21963 */ 21964 private class PackageFreezer implements AutoCloseable { 21965 private final String mPackageName; 21966 private final PackageFreezer[] mChildren; 21967 21968 private final boolean mWeFroze; 21969 21970 private final AtomicBoolean mClosed = new AtomicBoolean(); 21971 private final CloseGuard mCloseGuard = CloseGuard.get(); 21972 21973 /** 21974 * Create and return a stub freezer that doesn't actually do anything, 21975 * typically used when someone requested 21976 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 21977 * {@link PackageManager#DELETE_DONT_KILL_APP}. 21978 */ 21979 public PackageFreezer() { 21980 mPackageName = null; 21981 mChildren = null; 21982 mWeFroze = false; 21983 mCloseGuard.open("close"); 21984 } 21985 21986 public PackageFreezer(String packageName, int userId, String killReason) { 21987 synchronized (mPackages) { 21988 mPackageName = packageName; 21989 mWeFroze = mFrozenPackages.add(mPackageName); 21990 21991 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 21992 if (ps != null) { 21993 killApplication(ps.name, ps.appId, userId, killReason); 21994 } 21995 21996 final PackageParser.Package p = mPackages.get(packageName); 21997 if (p != null && p.childPackages != null) { 21998 final int N = p.childPackages.size(); 21999 mChildren = new PackageFreezer[N]; 22000 for (int i = 0; i < N; i++) { 22001 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 22002 userId, killReason); 22003 } 22004 } else { 22005 mChildren = null; 22006 } 22007 } 22008 mCloseGuard.open("close"); 22009 } 22010 22011 @Override 22012 protected void finalize() throws Throwable { 22013 try { 22014 mCloseGuard.warnIfOpen(); 22015 close(); 22016 } finally { 22017 super.finalize(); 22018 } 22019 } 22020 22021 @Override 22022 public void close() { 22023 mCloseGuard.close(); 22024 if (mClosed.compareAndSet(false, true)) { 22025 synchronized (mPackages) { 22026 if (mWeFroze) { 22027 mFrozenPackages.remove(mPackageName); 22028 } 22029 22030 if (mChildren != null) { 22031 for (PackageFreezer freezer : mChildren) { 22032 freezer.close(); 22033 } 22034 } 22035 } 22036 } 22037 } 22038 } 22039 22040 /** 22041 * Verify that given package is currently frozen. 22042 */ 22043 private void checkPackageFrozen(String packageName) { 22044 synchronized (mPackages) { 22045 if (!mFrozenPackages.contains(packageName)) { 22046 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 22047 } 22048 } 22049 } 22050 22051 @Override 22052 public int movePackage(final String packageName, final String volumeUuid) { 22053 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 22054 22055 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 22056 final int moveId = mNextMoveId.getAndIncrement(); 22057 mHandler.post(new Runnable() { 22058 @Override 22059 public void run() { 22060 try { 22061 movePackageInternal(packageName, volumeUuid, moveId, user); 22062 } catch (PackageManagerException e) { 22063 Slog.w(TAG, "Failed to move " + packageName, e); 22064 mMoveCallbacks.notifyStatusChanged(moveId, 22065 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 22066 } 22067 } 22068 }); 22069 return moveId; 22070 } 22071 22072 private void movePackageInternal(final String packageName, final String volumeUuid, 22073 final int moveId, UserHandle user) throws PackageManagerException { 22074 final StorageManager storage = mContext.getSystemService(StorageManager.class); 22075 final PackageManager pm = mContext.getPackageManager(); 22076 22077 final boolean currentAsec; 22078 final String currentVolumeUuid; 22079 final File codeFile; 22080 final String installerPackageName; 22081 final String packageAbiOverride; 22082 final int appId; 22083 final String seinfo; 22084 final String label; 22085 final int targetSdkVersion; 22086 final PackageFreezer freezer; 22087 final int[] installedUserIds; 22088 22089 // reader 22090 synchronized (mPackages) { 22091 final PackageParser.Package pkg = mPackages.get(packageName); 22092 final PackageSetting ps = mSettings.mPackages.get(packageName); 22093 if (pkg == null || ps == null) { 22094 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 22095 } 22096 22097 if (pkg.applicationInfo.isSystemApp()) { 22098 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 22099 "Cannot move system application"); 22100 } 22101 22102 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid); 22103 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean( 22104 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal); 22105 if (isInternalStorage && !allow3rdPartyOnInternal) { 22106 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL, 22107 "3rd party apps are not allowed on internal storage"); 22108 } 22109 22110 if (pkg.applicationInfo.isExternalAsec()) { 22111 currentAsec = true; 22112 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 22113 } else if (pkg.applicationInfo.isForwardLocked()) { 22114 currentAsec = true; 22115 currentVolumeUuid = "forward_locked"; 22116 } else { 22117 currentAsec = false; 22118 currentVolumeUuid = ps.volumeUuid; 22119 22120 final File probe = new File(pkg.codePath); 22121 final File probeOat = new File(probe, "oat"); 22122 if (!probe.isDirectory() || !probeOat.isDirectory()) { 22123 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22124 "Move only supported for modern cluster style installs"); 22125 } 22126 } 22127 22128 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 22129 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22130 "Package already moved to " + volumeUuid); 22131 } 22132 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 22133 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 22134 "Device admin cannot be moved"); 22135 } 22136 22137 if (mFrozenPackages.contains(packageName)) { 22138 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 22139 "Failed to move already frozen package"); 22140 } 22141 22142 codeFile = new File(pkg.codePath); 22143 installerPackageName = ps.installerPackageName; 22144 packageAbiOverride = ps.cpuAbiOverrideString; 22145 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 22146 seinfo = pkg.applicationInfo.seInfo; 22147 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 22148 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 22149 freezer = freezePackage(packageName, "movePackageInternal"); 22150 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 22151 } 22152 22153 final Bundle extras = new Bundle(); 22154 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 22155 extras.putString(Intent.EXTRA_TITLE, label); 22156 mMoveCallbacks.notifyCreated(moveId, extras); 22157 22158 int installFlags; 22159 final boolean moveCompleteApp; 22160 final File measurePath; 22161 22162 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 22163 installFlags = INSTALL_INTERNAL; 22164 moveCompleteApp = !currentAsec; 22165 measurePath = Environment.getDataAppDirectory(volumeUuid); 22166 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 22167 installFlags = INSTALL_EXTERNAL; 22168 moveCompleteApp = false; 22169 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 22170 } else { 22171 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 22172 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 22173 || !volume.isMountedWritable()) { 22174 freezer.close(); 22175 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22176 "Move location not mounted private volume"); 22177 } 22178 22179 Preconditions.checkState(!currentAsec); 22180 22181 installFlags = INSTALL_INTERNAL; 22182 moveCompleteApp = true; 22183 measurePath = Environment.getDataAppDirectory(volumeUuid); 22184 } 22185 22186 final PackageStats stats = new PackageStats(null, -1); 22187 synchronized (mInstaller) { 22188 for (int userId : installedUserIds) { 22189 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 22190 freezer.close(); 22191 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22192 "Failed to measure package size"); 22193 } 22194 } 22195 } 22196 22197 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 22198 + stats.dataSize); 22199 22200 final long startFreeBytes = measurePath.getFreeSpace(); 22201 final long sizeBytes; 22202 if (moveCompleteApp) { 22203 sizeBytes = stats.codeSize + stats.dataSize; 22204 } else { 22205 sizeBytes = stats.codeSize; 22206 } 22207 22208 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 22209 freezer.close(); 22210 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22211 "Not enough free space to move"); 22212 } 22213 22214 mMoveCallbacks.notifyStatusChanged(moveId, 10); 22215 22216 final CountDownLatch installedLatch = new CountDownLatch(1); 22217 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 22218 @Override 22219 public void onUserActionRequired(Intent intent) throws RemoteException { 22220 throw new IllegalStateException(); 22221 } 22222 22223 @Override 22224 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 22225 Bundle extras) throws RemoteException { 22226 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 22227 + PackageManager.installStatusToString(returnCode, msg)); 22228 22229 installedLatch.countDown(); 22230 freezer.close(); 22231 22232 final int status = PackageManager.installStatusToPublicStatus(returnCode); 22233 switch (status) { 22234 case PackageInstaller.STATUS_SUCCESS: 22235 mMoveCallbacks.notifyStatusChanged(moveId, 22236 PackageManager.MOVE_SUCCEEDED); 22237 break; 22238 case PackageInstaller.STATUS_FAILURE_STORAGE: 22239 mMoveCallbacks.notifyStatusChanged(moveId, 22240 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 22241 break; 22242 default: 22243 mMoveCallbacks.notifyStatusChanged(moveId, 22244 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 22245 break; 22246 } 22247 } 22248 }; 22249 22250 final MoveInfo move; 22251 if (moveCompleteApp) { 22252 // Kick off a thread to report progress estimates 22253 new Thread() { 22254 @Override 22255 public void run() { 22256 while (true) { 22257 try { 22258 if (installedLatch.await(1, TimeUnit.SECONDS)) { 22259 break; 22260 } 22261 } catch (InterruptedException ignored) { 22262 } 22263 22264 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 22265 final int progress = 10 + (int) MathUtils.constrain( 22266 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 22267 mMoveCallbacks.notifyStatusChanged(moveId, progress); 22268 } 22269 } 22270 }.start(); 22271 22272 final String dataAppName = codeFile.getName(); 22273 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 22274 dataAppName, appId, seinfo, targetSdkVersion); 22275 } else { 22276 move = null; 22277 } 22278 22279 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 22280 22281 final Message msg = mHandler.obtainMessage(INIT_COPY); 22282 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 22283 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 22284 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 22285 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/, 22286 PackageManager.INSTALL_REASON_UNKNOWN); 22287 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 22288 msg.obj = params; 22289 22290 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 22291 System.identityHashCode(msg.obj)); 22292 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 22293 System.identityHashCode(msg.obj)); 22294 22295 mHandler.sendMessage(msg); 22296 } 22297 22298 @Override 22299 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 22300 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 22301 22302 final int realMoveId = mNextMoveId.getAndIncrement(); 22303 final Bundle extras = new Bundle(); 22304 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 22305 mMoveCallbacks.notifyCreated(realMoveId, extras); 22306 22307 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 22308 @Override 22309 public void onCreated(int moveId, Bundle extras) { 22310 // Ignored 22311 } 22312 22313 @Override 22314 public void onStatusChanged(int moveId, int status, long estMillis) { 22315 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 22316 } 22317 }; 22318 22319 final StorageManager storage = mContext.getSystemService(StorageManager.class); 22320 storage.setPrimaryStorageUuid(volumeUuid, callback); 22321 return realMoveId; 22322 } 22323 22324 @Override 22325 public int getMoveStatus(int moveId) { 22326 mContext.enforceCallingOrSelfPermission( 22327 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22328 return mMoveCallbacks.mLastStatus.get(moveId); 22329 } 22330 22331 @Override 22332 public void registerMoveCallback(IPackageMoveObserver callback) { 22333 mContext.enforceCallingOrSelfPermission( 22334 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22335 mMoveCallbacks.register(callback); 22336 } 22337 22338 @Override 22339 public void unregisterMoveCallback(IPackageMoveObserver callback) { 22340 mContext.enforceCallingOrSelfPermission( 22341 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22342 mMoveCallbacks.unregister(callback); 22343 } 22344 22345 @Override 22346 public boolean setInstallLocation(int loc) { 22347 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 22348 null); 22349 if (getInstallLocation() == loc) { 22350 return true; 22351 } 22352 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 22353 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 22354 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 22355 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 22356 return true; 22357 } 22358 return false; 22359 } 22360 22361 @Override 22362 public int getInstallLocation() { 22363 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 22364 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 22365 PackageHelper.APP_INSTALL_AUTO); 22366 } 22367 22368 /** Called by UserManagerService */ 22369 void cleanUpUser(UserManagerService userManager, int userHandle) { 22370 synchronized (mPackages) { 22371 mDirtyUsers.remove(userHandle); 22372 mUserNeedsBadging.delete(userHandle); 22373 mSettings.removeUserLPw(userHandle); 22374 mPendingBroadcasts.remove(userHandle); 22375 mInstantAppRegistry.onUserRemovedLPw(userHandle); 22376 removeUnusedPackagesLPw(userManager, userHandle); 22377 } 22378 } 22379 22380 /** 22381 * We're removing userHandle and would like to remove any downloaded packages 22382 * that are no longer in use by any other user. 22383 * @param userHandle the user being removed 22384 */ 22385 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 22386 final boolean DEBUG_CLEAN_APKS = false; 22387 int [] users = userManager.getUserIds(); 22388 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 22389 while (psit.hasNext()) { 22390 PackageSetting ps = psit.next(); 22391 if (ps.pkg == null) { 22392 continue; 22393 } 22394 final String packageName = ps.pkg.packageName; 22395 // Skip over if system app 22396 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 22397 continue; 22398 } 22399 if (DEBUG_CLEAN_APKS) { 22400 Slog.i(TAG, "Checking package " + packageName); 22401 } 22402 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 22403 if (keep) { 22404 if (DEBUG_CLEAN_APKS) { 22405 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 22406 } 22407 } else { 22408 for (int i = 0; i < users.length; i++) { 22409 if (users[i] != userHandle && ps.getInstalled(users[i])) { 22410 keep = true; 22411 if (DEBUG_CLEAN_APKS) { 22412 Slog.i(TAG, " Keeping package " + packageName + " for user " 22413 + users[i]); 22414 } 22415 break; 22416 } 22417 } 22418 } 22419 if (!keep) { 22420 if (DEBUG_CLEAN_APKS) { 22421 Slog.i(TAG, " Removing package " + packageName); 22422 } 22423 mHandler.post(new Runnable() { 22424 public void run() { 22425 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, 22426 userHandle, 0); 22427 } //end run 22428 }); 22429 } 22430 } 22431 } 22432 22433 /** Called by UserManagerService */ 22434 void createNewUser(int userId, String[] disallowedPackages) { 22435 synchronized (mInstallLock) { 22436 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages); 22437 } 22438 synchronized (mPackages) { 22439 scheduleWritePackageRestrictionsLocked(userId); 22440 scheduleWritePackageListLocked(userId); 22441 applyFactoryDefaultBrowserLPw(userId); 22442 primeDomainVerificationsLPw(userId); 22443 } 22444 } 22445 22446 void onNewUserCreated(final int userId) { 22447 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 22448 // If permission review for legacy apps is required, we represent 22449 // dagerous permissions for such apps as always granted runtime 22450 // permissions to keep per user flag state whether review is needed. 22451 // Hence, if a new user is added we have to propagate dangerous 22452 // permission grants for these legacy apps. 22453 if (mPermissionReviewRequired) { 22454 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 22455 | UPDATE_PERMISSIONS_REPLACE_ALL); 22456 } 22457 } 22458 22459 @Override 22460 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 22461 mContext.enforceCallingOrSelfPermission( 22462 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 22463 "Only package verification agents can read the verifier device identity"); 22464 22465 synchronized (mPackages) { 22466 return mSettings.getVerifierDeviceIdentityLPw(); 22467 } 22468 } 22469 22470 @Override 22471 public void setPermissionEnforced(String permission, boolean enforced) { 22472 // TODO: Now that we no longer change GID for storage, this should to away. 22473 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 22474 "setPermissionEnforced"); 22475 if (READ_EXTERNAL_STORAGE.equals(permission)) { 22476 synchronized (mPackages) { 22477 if (mSettings.mReadExternalStorageEnforced == null 22478 || mSettings.mReadExternalStorageEnforced != enforced) { 22479 mSettings.mReadExternalStorageEnforced = enforced; 22480 mSettings.writeLPr(); 22481 } 22482 } 22483 // kill any non-foreground processes so we restart them and 22484 // grant/revoke the GID. 22485 final IActivityManager am = ActivityManager.getService(); 22486 if (am != null) { 22487 final long token = Binder.clearCallingIdentity(); 22488 try { 22489 am.killProcessesBelowForeground("setPermissionEnforcement"); 22490 } catch (RemoteException e) { 22491 } finally { 22492 Binder.restoreCallingIdentity(token); 22493 } 22494 } 22495 } else { 22496 throw new IllegalArgumentException("No selective enforcement for " + permission); 22497 } 22498 } 22499 22500 @Override 22501 @Deprecated 22502 public boolean isPermissionEnforced(String permission) { 22503 return true; 22504 } 22505 22506 @Override 22507 public boolean isStorageLow() { 22508 final long token = Binder.clearCallingIdentity(); 22509 try { 22510 final DeviceStorageMonitorInternal 22511 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 22512 if (dsm != null) { 22513 return dsm.isMemoryLow(); 22514 } else { 22515 return false; 22516 } 22517 } finally { 22518 Binder.restoreCallingIdentity(token); 22519 } 22520 } 22521 22522 @Override 22523 public IPackageInstaller getPackageInstaller() { 22524 return mInstallerService; 22525 } 22526 22527 private boolean userNeedsBadging(int userId) { 22528 int index = mUserNeedsBadging.indexOfKey(userId); 22529 if (index < 0) { 22530 final UserInfo userInfo; 22531 final long token = Binder.clearCallingIdentity(); 22532 try { 22533 userInfo = sUserManager.getUserInfo(userId); 22534 } finally { 22535 Binder.restoreCallingIdentity(token); 22536 } 22537 final boolean b; 22538 if (userInfo != null && userInfo.isManagedProfile()) { 22539 b = true; 22540 } else { 22541 b = false; 22542 } 22543 mUserNeedsBadging.put(userId, b); 22544 return b; 22545 } 22546 return mUserNeedsBadging.valueAt(index); 22547 } 22548 22549 @Override 22550 public KeySet getKeySetByAlias(String packageName, String alias) { 22551 if (packageName == null || alias == null) { 22552 return null; 22553 } 22554 synchronized(mPackages) { 22555 final PackageParser.Package pkg = mPackages.get(packageName); 22556 if (pkg == null) { 22557 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22558 throw new IllegalArgumentException("Unknown package: " + packageName); 22559 } 22560 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22561 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 22562 } 22563 } 22564 22565 @Override 22566 public KeySet getSigningKeySet(String packageName) { 22567 if (packageName == null) { 22568 return null; 22569 } 22570 synchronized(mPackages) { 22571 final PackageParser.Package pkg = mPackages.get(packageName); 22572 if (pkg == null) { 22573 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22574 throw new IllegalArgumentException("Unknown package: " + packageName); 22575 } 22576 if (pkg.applicationInfo.uid != Binder.getCallingUid() 22577 && Process.SYSTEM_UID != Binder.getCallingUid()) { 22578 throw new SecurityException("May not access signing KeySet of other apps."); 22579 } 22580 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22581 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 22582 } 22583 } 22584 22585 @Override 22586 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 22587 if (packageName == null || ks == null) { 22588 return false; 22589 } 22590 synchronized(mPackages) { 22591 final PackageParser.Package pkg = mPackages.get(packageName); 22592 if (pkg == null) { 22593 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22594 throw new IllegalArgumentException("Unknown package: " + packageName); 22595 } 22596 IBinder ksh = ks.getToken(); 22597 if (ksh instanceof KeySetHandle) { 22598 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22599 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 22600 } 22601 return false; 22602 } 22603 } 22604 22605 @Override 22606 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 22607 if (packageName == null || ks == null) { 22608 return false; 22609 } 22610 synchronized(mPackages) { 22611 final PackageParser.Package pkg = mPackages.get(packageName); 22612 if (pkg == null) { 22613 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22614 throw new IllegalArgumentException("Unknown package: " + packageName); 22615 } 22616 IBinder ksh = ks.getToken(); 22617 if (ksh instanceof KeySetHandle) { 22618 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22619 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 22620 } 22621 return false; 22622 } 22623 } 22624 22625 private void deletePackageIfUnusedLPr(final String packageName) { 22626 PackageSetting ps = mSettings.mPackages.get(packageName); 22627 if (ps == null) { 22628 return; 22629 } 22630 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 22631 // TODO Implement atomic delete if package is unused 22632 // It is currently possible that the package will be deleted even if it is installed 22633 // after this method returns. 22634 mHandler.post(new Runnable() { 22635 public void run() { 22636 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, 22637 0, PackageManager.DELETE_ALL_USERS); 22638 } 22639 }); 22640 } 22641 } 22642 22643 /** 22644 * Check and throw if the given before/after packages would be considered a 22645 * downgrade. 22646 */ 22647 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 22648 throws PackageManagerException { 22649 if (after.versionCode < before.mVersionCode) { 22650 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22651 "Update version code " + after.versionCode + " is older than current " 22652 + before.mVersionCode); 22653 } else if (after.versionCode == before.mVersionCode) { 22654 if (after.baseRevisionCode < before.baseRevisionCode) { 22655 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22656 "Update base revision code " + after.baseRevisionCode 22657 + " is older than current " + before.baseRevisionCode); 22658 } 22659 22660 if (!ArrayUtils.isEmpty(after.splitNames)) { 22661 for (int i = 0; i < after.splitNames.length; i++) { 22662 final String splitName = after.splitNames[i]; 22663 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 22664 if (j != -1) { 22665 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 22666 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22667 "Update split " + splitName + " revision code " 22668 + after.splitRevisionCodes[i] + " is older than current " 22669 + before.splitRevisionCodes[j]); 22670 } 22671 } 22672 } 22673 } 22674 } 22675 } 22676 22677 private static class MoveCallbacks extends Handler { 22678 private static final int MSG_CREATED = 1; 22679 private static final int MSG_STATUS_CHANGED = 2; 22680 22681 private final RemoteCallbackList<IPackageMoveObserver> 22682 mCallbacks = new RemoteCallbackList<>(); 22683 22684 private final SparseIntArray mLastStatus = new SparseIntArray(); 22685 22686 public MoveCallbacks(Looper looper) { 22687 super(looper); 22688 } 22689 22690 public void register(IPackageMoveObserver callback) { 22691 mCallbacks.register(callback); 22692 } 22693 22694 public void unregister(IPackageMoveObserver callback) { 22695 mCallbacks.unregister(callback); 22696 } 22697 22698 @Override 22699 public void handleMessage(Message msg) { 22700 final SomeArgs args = (SomeArgs) msg.obj; 22701 final int n = mCallbacks.beginBroadcast(); 22702 for (int i = 0; i < n; i++) { 22703 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 22704 try { 22705 invokeCallback(callback, msg.what, args); 22706 } catch (RemoteException ignored) { 22707 } 22708 } 22709 mCallbacks.finishBroadcast(); 22710 args.recycle(); 22711 } 22712 22713 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 22714 throws RemoteException { 22715 switch (what) { 22716 case MSG_CREATED: { 22717 callback.onCreated(args.argi1, (Bundle) args.arg2); 22718 break; 22719 } 22720 case MSG_STATUS_CHANGED: { 22721 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 22722 break; 22723 } 22724 } 22725 } 22726 22727 private void notifyCreated(int moveId, Bundle extras) { 22728 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 22729 22730 final SomeArgs args = SomeArgs.obtain(); 22731 args.argi1 = moveId; 22732 args.arg2 = extras; 22733 obtainMessage(MSG_CREATED, args).sendToTarget(); 22734 } 22735 22736 private void notifyStatusChanged(int moveId, int status) { 22737 notifyStatusChanged(moveId, status, -1); 22738 } 22739 22740 private void notifyStatusChanged(int moveId, int status, long estMillis) { 22741 Slog.v(TAG, "Move " + moveId + " status " + status); 22742 22743 final SomeArgs args = SomeArgs.obtain(); 22744 args.argi1 = moveId; 22745 args.argi2 = status; 22746 args.arg3 = estMillis; 22747 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 22748 22749 synchronized (mLastStatus) { 22750 mLastStatus.put(moveId, status); 22751 } 22752 } 22753 } 22754 22755 private final static class OnPermissionChangeListeners extends Handler { 22756 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 22757 22758 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 22759 new RemoteCallbackList<>(); 22760 22761 public OnPermissionChangeListeners(Looper looper) { 22762 super(looper); 22763 } 22764 22765 @Override 22766 public void handleMessage(Message msg) { 22767 switch (msg.what) { 22768 case MSG_ON_PERMISSIONS_CHANGED: { 22769 final int uid = msg.arg1; 22770 handleOnPermissionsChanged(uid); 22771 } break; 22772 } 22773 } 22774 22775 public void addListenerLocked(IOnPermissionsChangeListener listener) { 22776 mPermissionListeners.register(listener); 22777 22778 } 22779 22780 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 22781 mPermissionListeners.unregister(listener); 22782 } 22783 22784 public void onPermissionsChanged(int uid) { 22785 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 22786 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 22787 } 22788 } 22789 22790 private void handleOnPermissionsChanged(int uid) { 22791 final int count = mPermissionListeners.beginBroadcast(); 22792 try { 22793 for (int i = 0; i < count; i++) { 22794 IOnPermissionsChangeListener callback = mPermissionListeners 22795 .getBroadcastItem(i); 22796 try { 22797 callback.onPermissionsChanged(uid); 22798 } catch (RemoteException e) { 22799 Log.e(TAG, "Permission listener is dead", e); 22800 } 22801 } 22802 } finally { 22803 mPermissionListeners.finishBroadcast(); 22804 } 22805 } 22806 } 22807 22808 private class PackageManagerInternalImpl extends PackageManagerInternal { 22809 @Override 22810 public void setLocationPackagesProvider(PackagesProvider provider) { 22811 synchronized (mPackages) { 22812 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 22813 } 22814 } 22815 22816 @Override 22817 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 22818 synchronized (mPackages) { 22819 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 22820 } 22821 } 22822 22823 @Override 22824 public void setSmsAppPackagesProvider(PackagesProvider provider) { 22825 synchronized (mPackages) { 22826 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 22827 } 22828 } 22829 22830 @Override 22831 public void setDialerAppPackagesProvider(PackagesProvider provider) { 22832 synchronized (mPackages) { 22833 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 22834 } 22835 } 22836 22837 @Override 22838 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 22839 synchronized (mPackages) { 22840 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 22841 } 22842 } 22843 22844 @Override 22845 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 22846 synchronized (mPackages) { 22847 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 22848 } 22849 } 22850 22851 @Override 22852 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 22853 synchronized (mPackages) { 22854 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 22855 packageName, userId); 22856 } 22857 } 22858 22859 @Override 22860 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 22861 synchronized (mPackages) { 22862 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 22863 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 22864 packageName, userId); 22865 } 22866 } 22867 22868 @Override 22869 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 22870 synchronized (mPackages) { 22871 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 22872 packageName, userId); 22873 } 22874 } 22875 22876 @Override 22877 public void setKeepUninstalledPackages(final List<String> packageList) { 22878 Preconditions.checkNotNull(packageList); 22879 List<String> removedFromList = null; 22880 synchronized (mPackages) { 22881 if (mKeepUninstalledPackages != null) { 22882 final int packagesCount = mKeepUninstalledPackages.size(); 22883 for (int i = 0; i < packagesCount; i++) { 22884 String oldPackage = mKeepUninstalledPackages.get(i); 22885 if (packageList != null && packageList.contains(oldPackage)) { 22886 continue; 22887 } 22888 if (removedFromList == null) { 22889 removedFromList = new ArrayList<>(); 22890 } 22891 removedFromList.add(oldPackage); 22892 } 22893 } 22894 mKeepUninstalledPackages = new ArrayList<>(packageList); 22895 if (removedFromList != null) { 22896 final int removedCount = removedFromList.size(); 22897 for (int i = 0; i < removedCount; i++) { 22898 deletePackageIfUnusedLPr(removedFromList.get(i)); 22899 } 22900 } 22901 } 22902 } 22903 22904 @Override 22905 public boolean isPermissionsReviewRequired(String packageName, int userId) { 22906 synchronized (mPackages) { 22907 // If we do not support permission review, done. 22908 if (!mPermissionReviewRequired) { 22909 return false; 22910 } 22911 22912 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 22913 if (packageSetting == null) { 22914 return false; 22915 } 22916 22917 // Permission review applies only to apps not supporting the new permission model. 22918 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 22919 return false; 22920 } 22921 22922 // Legacy apps have the permission and get user consent on launch. 22923 PermissionsState permissionsState = packageSetting.getPermissionsState(); 22924 return permissionsState.isPermissionReviewRequired(userId); 22925 } 22926 } 22927 22928 @Override 22929 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 22930 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 22931 } 22932 22933 @Override 22934 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 22935 int userId) { 22936 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 22937 } 22938 22939 @Override 22940 public void setDeviceAndProfileOwnerPackages( 22941 int deviceOwnerUserId, String deviceOwnerPackage, 22942 SparseArray<String> profileOwnerPackages) { 22943 mProtectedPackages.setDeviceAndProfileOwnerPackages( 22944 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 22945 } 22946 22947 @Override 22948 public boolean isPackageDataProtected(int userId, String packageName) { 22949 return mProtectedPackages.isPackageDataProtected(userId, packageName); 22950 } 22951 22952 @Override 22953 public boolean isPackageEphemeral(int userId, String packageName) { 22954 synchronized (mPackages) { 22955 final PackageSetting ps = mSettings.mPackages.get(packageName); 22956 return ps != null ? ps.getInstantApp(userId) : false; 22957 } 22958 } 22959 22960 @Override 22961 public boolean wasPackageEverLaunched(String packageName, int userId) { 22962 synchronized (mPackages) { 22963 return mSettings.wasPackageEverLaunchedLPr(packageName, userId); 22964 } 22965 } 22966 22967 @Override 22968 public void grantRuntimePermission(String packageName, String name, int userId, 22969 boolean overridePolicy) { 22970 PackageManagerService.this.grantRuntimePermission(packageName, name, userId, 22971 overridePolicy); 22972 } 22973 22974 @Override 22975 public void revokeRuntimePermission(String packageName, String name, int userId, 22976 boolean overridePolicy) { 22977 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId, 22978 overridePolicy); 22979 } 22980 22981 @Override 22982 public String getNameForUid(int uid) { 22983 return PackageManagerService.this.getNameForUid(uid); 22984 } 22985 22986 @Override 22987 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, 22988 Intent origIntent, String resolvedType, String callingPackage, int userId) { 22989 PackageManagerService.this.requestInstantAppResolutionPhaseTwo( 22990 responseObj, origIntent, resolvedType, callingPackage, userId); 22991 } 22992 22993 @Override 22994 public void grantEphemeralAccess(int userId, Intent intent, 22995 int targetAppId, int ephemeralAppId) { 22996 synchronized (mPackages) { 22997 mInstantAppRegistry.grantInstantAccessLPw(userId, intent, 22998 targetAppId, ephemeralAppId); 22999 } 23000 } 23001 23002 @Override 23003 public void pruneInstantApps() { 23004 synchronized (mPackages) { 23005 mInstantAppRegistry.pruneInstantAppsLPw(); 23006 } 23007 } 23008 23009 @Override 23010 public String getSetupWizardPackageName() { 23011 return mSetupWizardPackage; 23012 } 23013 23014 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) { 23015 if (policy != null) { 23016 mExternalSourcesPolicy = policy; 23017 } 23018 } 23019 23020 @Override 23021 public boolean isPackagePersistent(String packageName) { 23022 synchronized (mPackages) { 23023 PackageParser.Package pkg = mPackages.get(packageName); 23024 return pkg != null 23025 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM 23026 | ApplicationInfo.FLAG_PERSISTENT)) == 23027 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT)) 23028 : false; 23029 } 23030 } 23031 23032 @Override 23033 public List<PackageInfo> getOverlayPackages(int userId) { 23034 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>(); 23035 synchronized (mPackages) { 23036 for (PackageParser.Package p : mPackages.values()) { 23037 if (p.mOverlayTarget != null) { 23038 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId); 23039 if (pkg != null) { 23040 overlayPackages.add(pkg); 23041 } 23042 } 23043 } 23044 } 23045 return overlayPackages; 23046 } 23047 23048 @Override 23049 public List<String> getTargetPackageNames(int userId) { 23050 List<String> targetPackages = new ArrayList<>(); 23051 synchronized (mPackages) { 23052 for (PackageParser.Package p : mPackages.values()) { 23053 if (p.mOverlayTarget == null) { 23054 targetPackages.add(p.packageName); 23055 } 23056 } 23057 } 23058 return targetPackages; 23059 } 23060 23061 @Override 23062 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName, 23063 @Nullable List<String> overlayPackageNames) { 23064 synchronized (mPackages) { 23065 if (targetPackageName == null || mPackages.get(targetPackageName) == null) { 23066 Slog.e(TAG, "failed to find package " + targetPackageName); 23067 return false; 23068 } 23069 23070 ArrayList<String> paths = null; 23071 if (overlayPackageNames != null) { 23072 final int N = overlayPackageNames.size(); 23073 paths = new ArrayList<>(N); 23074 for (int i = 0; i < N; i++) { 23075 final String packageName = overlayPackageNames.get(i); 23076 final PackageParser.Package pkg = mPackages.get(packageName); 23077 if (pkg == null) { 23078 Slog.e(TAG, "failed to find package " + packageName); 23079 return false; 23080 } 23081 paths.add(pkg.baseCodePath); 23082 } 23083 } 23084 23085 ArrayMap<String, ArrayList<String>> userSpecificOverlays = 23086 mEnabledOverlayPaths.get(userId); 23087 if (userSpecificOverlays == null) { 23088 userSpecificOverlays = new ArrayMap<>(); 23089 mEnabledOverlayPaths.put(userId, userSpecificOverlays); 23090 } 23091 23092 if (paths != null && paths.size() > 0) { 23093 userSpecificOverlays.put(targetPackageName, paths); 23094 } else { 23095 userSpecificOverlays.remove(targetPackageName); 23096 } 23097 return true; 23098 } 23099 } 23100 23101 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 23102 int flags, int userId) { 23103 return resolveIntentInternal( 23104 intent, resolvedType, flags, userId, true /*includeInstantApp*/); 23105 } 23106 } 23107 23108 @Override 23109 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 23110 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 23111 synchronized (mPackages) { 23112 final long identity = Binder.clearCallingIdentity(); 23113 try { 23114 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 23115 packageNames, userId); 23116 } finally { 23117 Binder.restoreCallingIdentity(identity); 23118 } 23119 } 23120 } 23121 23122 @Override 23123 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) { 23124 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices"); 23125 synchronized (mPackages) { 23126 final long identity = Binder.clearCallingIdentity(); 23127 try { 23128 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr( 23129 packageNames, userId); 23130 } finally { 23131 Binder.restoreCallingIdentity(identity); 23132 } 23133 } 23134 } 23135 23136 private static void enforceSystemOrPhoneCaller(String tag) { 23137 int callingUid = Binder.getCallingUid(); 23138 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 23139 throw new SecurityException( 23140 "Cannot call " + tag + " from UID " + callingUid); 23141 } 23142 } 23143 23144 boolean isHistoricalPackageUsageAvailable() { 23145 return mPackageUsage.isHistoricalPackageUsageAvailable(); 23146 } 23147 23148 /** 23149 * Return a <b>copy</b> of the collection of packages known to the package manager. 23150 * @return A copy of the values of mPackages. 23151 */ 23152 Collection<PackageParser.Package> getPackages() { 23153 synchronized (mPackages) { 23154 return new ArrayList<>(mPackages.values()); 23155 } 23156 } 23157 23158 /** 23159 * Logs process start information (including base APK hash) to the security log. 23160 * @hide 23161 */ 23162 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 23163 String apkFile, int pid) { 23164 if (!SecurityLog.isLoggingEnabled()) { 23165 return; 23166 } 23167 Bundle data = new Bundle(); 23168 data.putLong("startTimestamp", System.currentTimeMillis()); 23169 data.putString("processName", processName); 23170 data.putInt("uid", uid); 23171 data.putString("seinfo", seinfo); 23172 data.putString("apkFile", apkFile); 23173 data.putInt("pid", pid); 23174 Message msg = mProcessLoggingHandler.obtainMessage( 23175 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 23176 msg.setData(data); 23177 mProcessLoggingHandler.sendMessage(msg); 23178 } 23179 23180 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 23181 return mCompilerStats.getPackageStats(pkgName); 23182 } 23183 23184 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 23185 return getOrCreateCompilerPackageStats(pkg.packageName); 23186 } 23187 23188 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 23189 return mCompilerStats.getOrCreatePackageStats(pkgName); 23190 } 23191 23192 public void deleteCompilerPackageStats(String pkgName) { 23193 mCompilerStats.deletePackageStats(pkgName); 23194 } 23195 23196 @Override 23197 public int getInstallReason(String packageName, int userId) { 23198 enforceCrossUserPermission(Binder.getCallingUid(), userId, 23199 true /* requireFullPermission */, false /* checkShell */, 23200 "get install reason"); 23201 synchronized (mPackages) { 23202 final PackageSetting ps = mSettings.mPackages.get(packageName); 23203 if (ps != null) { 23204 return ps.getInstallReason(userId); 23205 } 23206 } 23207 return PackageManager.INSTALL_REASON_UNKNOWN; 23208 } 23209 23210 @Override 23211 public boolean canRequestPackageInstalls(String packageName, int userId) { 23212 int callingUid = Binder.getCallingUid(); 23213 int uid = getPackageUid(packageName, 0, userId); 23214 if (callingUid != uid && callingUid != Process.ROOT_UID 23215 && callingUid != Process.SYSTEM_UID) { 23216 throw new SecurityException( 23217 "Caller uid " + callingUid + " does not own package " + packageName); 23218 } 23219 ApplicationInfo info = getApplicationInfo(packageName, 0, userId); 23220 if (info == null) { 23221 return false; 23222 } 23223 if (info.targetSdkVersion < Build.VERSION_CODES.O) { 23224 throw new UnsupportedOperationException( 23225 "Operation only supported on apps targeting Android O or higher"); 23226 } 23227 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES; 23228 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission); 23229 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) { 23230 throw new SecurityException("Need to declare " + appOpPermission + " to call this api"); 23231 } 23232 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) { 23233 return false; 23234 } 23235 if (mExternalSourcesPolicy != null) { 23236 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid); 23237 if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) { 23238 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED; 23239 } 23240 } 23241 return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED; 23242 } 23243} 23244