PackageManagerService.java revision 0f28a80d8e80a3546fe0776999b2deaa3dc2157c
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.DeviceIdleController; 264import com.android.server.EventLogTags; 265import com.android.server.FgThread; 266import com.android.server.IntentResolver; 267import com.android.server.LocalServices; 268import com.android.server.LockGuard; 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.BackgroundDexOptService; 275import com.android.server.pm.Installer.InstallerException; 276import com.android.server.pm.PermissionsState.PermissionState; 277import com.android.server.pm.Settings.DatabaseVersion; 278import com.android.server.pm.Settings.VersionInfo; 279import com.android.server.pm.dex.DexManager; 280import com.android.server.storage.DeviceStorageMonitorInternal; 281 282import dalvik.system.CloseGuard; 283import dalvik.system.DexFile; 284import dalvik.system.VMRuntime; 285 286import libcore.io.IoUtils; 287import libcore.util.EmptyArray; 288 289import org.xmlpull.v1.XmlPullParser; 290import org.xmlpull.v1.XmlPullParserException; 291import org.xmlpull.v1.XmlSerializer; 292 293import java.io.BufferedOutputStream; 294import java.io.BufferedReader; 295import java.io.ByteArrayInputStream; 296import java.io.ByteArrayOutputStream; 297import java.io.File; 298import java.io.FileDescriptor; 299import java.io.FileInputStream; 300import java.io.FileNotFoundException; 301import java.io.FileOutputStream; 302import java.io.FileReader; 303import java.io.FilenameFilter; 304import java.io.IOException; 305import java.io.PrintWriter; 306import java.nio.charset.StandardCharsets; 307import java.security.DigestInputStream; 308import java.security.MessageDigest; 309import java.security.NoSuchAlgorithmException; 310import java.security.PublicKey; 311import java.security.SecureRandom; 312import java.security.cert.Certificate; 313import java.security.cert.CertificateEncodingException; 314import java.security.cert.CertificateException; 315import java.text.SimpleDateFormat; 316import java.util.ArrayList; 317import java.util.Arrays; 318import java.util.Collection; 319import java.util.Collections; 320import java.util.Comparator; 321import java.util.Date; 322import java.util.HashMap; 323import java.util.HashSet; 324import java.util.Iterator; 325import java.util.List; 326import java.util.Map; 327import java.util.Objects; 328import java.util.Set; 329import java.util.concurrent.CountDownLatch; 330import java.util.concurrent.Future; 331import java.util.concurrent.TimeUnit; 332import java.util.concurrent.atomic.AtomicBoolean; 333import java.util.concurrent.atomic.AtomicInteger; 334 335/** 336 * Keep track of all those APKs everywhere. 337 * <p> 338 * Internally there are two important locks: 339 * <ul> 340 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 341 * and other related state. It is a fine-grained lock that should only be held 342 * momentarily, as it's one of the most contended locks in the system. 343 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 344 * operations typically involve heavy lifting of application data on disk. Since 345 * {@code installd} is single-threaded, and it's operations can often be slow, 346 * this lock should never be acquired while already holding {@link #mPackages}. 347 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 348 * holding {@link #mInstallLock}. 349 * </ul> 350 * Many internal methods rely on the caller to hold the appropriate locks, and 351 * this contract is expressed through method name suffixes: 352 * <ul> 353 * <li>fooLI(): the caller must hold {@link #mInstallLock} 354 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 355 * being modified must be frozen 356 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 357 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 358 * </ul> 359 * <p> 360 * Because this class is very central to the platform's security; please run all 361 * CTS and unit tests whenever making modifications: 362 * 363 * <pre> 364 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 365 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases 366 * </pre> 367 */ 368public class PackageManagerService extends IPackageManager.Stub { 369 static final String TAG = "PackageManager"; 370 static final boolean DEBUG_SETTINGS = false; 371 static final boolean DEBUG_PREFERRED = false; 372 static final boolean DEBUG_UPGRADE = false; 373 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 374 private static final boolean DEBUG_BACKUP = false; 375 private static final boolean DEBUG_INSTALL = false; 376 private static final boolean DEBUG_REMOVE = false; 377 private static final boolean DEBUG_BROADCASTS = false; 378 private static final boolean DEBUG_SHOW_INFO = false; 379 private static final boolean DEBUG_PACKAGE_INFO = false; 380 private static final boolean DEBUG_INTENT_MATCHING = false; 381 private static final boolean DEBUG_PACKAGE_SCANNING = false; 382 private static final boolean DEBUG_VERIFY = false; 383 private static final boolean DEBUG_FILTERS = false; 384 385 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 386 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 387 // user, but by default initialize to this. 388 public static final boolean DEBUG_DEXOPT = false; 389 390 private static final boolean DEBUG_ABI_SELECTION = false; 391 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 392 private static final boolean DEBUG_TRIAGED_MISSING = false; 393 private static final boolean DEBUG_APP_DATA = false; 394 395 /** REMOVE. According to Svet, this was only used to reset permissions during development. */ 396 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 397 398 private static final boolean DISABLE_EPHEMERAL_APPS = false; 399 private static final boolean HIDE_EPHEMERAL_APIS = false; 400 401 private static final boolean ENABLE_FREE_CACHE_V2 = 402 SystemProperties.getBoolean("fw.free_cache_v2", true); 403 404 private static final int RADIO_UID = Process.PHONE_UID; 405 private static final int LOG_UID = Process.LOG_UID; 406 private static final int NFC_UID = Process.NFC_UID; 407 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 408 private static final int SHELL_UID = Process.SHELL_UID; 409 410 // Cap the size of permission trees that 3rd party apps can define 411 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 412 413 // Suffix used during package installation when copying/moving 414 // package apks to install directory. 415 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 416 417 static final int SCAN_NO_DEX = 1<<1; 418 static final int SCAN_FORCE_DEX = 1<<2; 419 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 420 static final int SCAN_NEW_INSTALL = 1<<4; 421 static final int SCAN_UPDATE_TIME = 1<<5; 422 static final int SCAN_BOOTING = 1<<6; 423 static final int SCAN_TRUSTED_OVERLAY = 1<<7; 424 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8; 425 static final int SCAN_REPLACING = 1<<9; 426 static final int SCAN_REQUIRE_KNOWN = 1<<10; 427 static final int SCAN_MOVE = 1<<11; 428 static final int SCAN_INITIAL = 1<<12; 429 static final int SCAN_CHECK_ONLY = 1<<13; 430 static final int SCAN_DONT_KILL_APP = 1<<14; 431 static final int SCAN_IGNORE_FROZEN = 1<<15; 432 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16; 433 static final int SCAN_AS_INSTANT_APP = 1<<17; 434 static final int SCAN_AS_FULL_APP = 1<<18; 435 /** Should not be with the scan flags */ 436 static final int FLAGS_REMOVE_CHATTY = 1<<31; 437 438 private static final String STATIC_SHARED_LIB_DELIMITER = "_"; 439 440 private static final int[] EMPTY_INT_ARRAY = new int[0]; 441 442 /** 443 * Timeout (in milliseconds) after which the watchdog should declare that 444 * our handler thread is wedged. The usual default for such things is one 445 * minute but we sometimes do very lengthy I/O operations on this thread, 446 * such as installing multi-gigabyte applications, so ours needs to be longer. 447 */ 448 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 449 450 /** 451 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 452 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 453 * settings entry if available, otherwise we use the hardcoded default. If it's been 454 * more than this long since the last fstrim, we force one during the boot sequence. 455 * 456 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 457 * one gets run at the next available charging+idle time. This final mandatory 458 * no-fstrim check kicks in only of the other scheduling criteria is never met. 459 */ 460 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 461 462 /** 463 * Whether verification is enabled by default. 464 */ 465 private static final boolean DEFAULT_VERIFY_ENABLE = true; 466 467 /** 468 * The default maximum time to wait for the verification agent to return in 469 * milliseconds. 470 */ 471 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 472 473 /** 474 * The default response for package verification timeout. 475 * 476 * This can be either PackageManager.VERIFICATION_ALLOW or 477 * PackageManager.VERIFICATION_REJECT. 478 */ 479 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 480 481 static final String PLATFORM_PACKAGE_NAME = "android"; 482 483 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 484 485 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 486 DEFAULT_CONTAINER_PACKAGE, 487 "com.android.defcontainer.DefaultContainerService"); 488 489 private static final String KILL_APP_REASON_GIDS_CHANGED = 490 "permission grant or revoke changed gids"; 491 492 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 493 "permissions revoked"; 494 495 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 496 497 private static final String PACKAGE_SCHEME = "package"; 498 499 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 500 501 /** Permission grant: not grant the permission. */ 502 private static final int GRANT_DENIED = 1; 503 504 /** Permission grant: grant the permission as an install permission. */ 505 private static final int GRANT_INSTALL = 2; 506 507 /** Permission grant: grant the permission as a runtime one. */ 508 private static final int GRANT_RUNTIME = 3; 509 510 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 511 private static final int GRANT_UPGRADE = 4; 512 513 /** Canonical intent used to identify what counts as a "web browser" app */ 514 private static final Intent sBrowserIntent; 515 static { 516 sBrowserIntent = new Intent(); 517 sBrowserIntent.setAction(Intent.ACTION_VIEW); 518 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 519 sBrowserIntent.setData(Uri.parse("http:")); 520 } 521 522 /** 523 * The set of all protected actions [i.e. those actions for which a high priority 524 * intent filter is disallowed]. 525 */ 526 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 527 static { 528 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 529 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 530 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 531 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 532 } 533 534 // Compilation reasons. 535 public static final int REASON_FIRST_BOOT = 0; 536 public static final int REASON_BOOT = 1; 537 public static final int REASON_INSTALL = 2; 538 public static final int REASON_BACKGROUND_DEXOPT = 3; 539 public static final int REASON_AB_OTA = 4; 540 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 541 public static final int REASON_SHARED_APK = 6; 542 public static final int REASON_FORCED_DEXOPT = 7; 543 public static final int REASON_CORE_APP = 8; 544 545 public static final int REASON_LAST = REASON_CORE_APP; 546 547 /** All dangerous permission names in the same order as the events in MetricsEvent */ 548 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList( 549 Manifest.permission.READ_CALENDAR, 550 Manifest.permission.WRITE_CALENDAR, 551 Manifest.permission.CAMERA, 552 Manifest.permission.READ_CONTACTS, 553 Manifest.permission.WRITE_CONTACTS, 554 Manifest.permission.GET_ACCOUNTS, 555 Manifest.permission.ACCESS_FINE_LOCATION, 556 Manifest.permission.ACCESS_COARSE_LOCATION, 557 Manifest.permission.RECORD_AUDIO, 558 Manifest.permission.READ_PHONE_STATE, 559 Manifest.permission.CALL_PHONE, 560 Manifest.permission.READ_CALL_LOG, 561 Manifest.permission.WRITE_CALL_LOG, 562 Manifest.permission.ADD_VOICEMAIL, 563 Manifest.permission.USE_SIP, 564 Manifest.permission.PROCESS_OUTGOING_CALLS, 565 Manifest.permission.READ_CELL_BROADCASTS, 566 Manifest.permission.BODY_SENSORS, 567 Manifest.permission.SEND_SMS, 568 Manifest.permission.RECEIVE_SMS, 569 Manifest.permission.READ_SMS, 570 Manifest.permission.RECEIVE_WAP_PUSH, 571 Manifest.permission.RECEIVE_MMS, 572 Manifest.permission.READ_EXTERNAL_STORAGE, 573 Manifest.permission.WRITE_EXTERNAL_STORAGE, 574 Manifest.permission.READ_PHONE_NUMBER, 575 Manifest.permission.ANSWER_PHONE_CALLS); 576 577 578 /** 579 * Version number for the package parser cache. Increment this whenever the format or 580 * extent of cached data changes. See {@code PackageParser#setCacheDir}. 581 */ 582 private static final String PACKAGE_PARSER_CACHE_VERSION = "1"; 583 584 /** 585 * Whether the package parser cache is enabled. 586 */ 587 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true; 588 589 final ServiceThread mHandlerThread; 590 591 final PackageHandler mHandler; 592 593 private final ProcessLoggingHandler mProcessLoggingHandler; 594 595 /** 596 * Messages for {@link #mHandler} that need to wait for system ready before 597 * being dispatched. 598 */ 599 private ArrayList<Message> mPostSystemReadyMessages; 600 601 final int mSdkVersion = Build.VERSION.SDK_INT; 602 603 final Context mContext; 604 final boolean mFactoryTest; 605 final boolean mOnlyCore; 606 final DisplayMetrics mMetrics; 607 final int mDefParseFlags; 608 final String[] mSeparateProcesses; 609 final boolean mIsUpgrade; 610 final boolean mIsPreNUpgrade; 611 final boolean mIsPreNMR1Upgrade; 612 613 @GuardedBy("mPackages") 614 private boolean mDexOptDialogShown; 615 616 /** The location for ASEC container files on internal storage. */ 617 final String mAsecInternalPath; 618 619 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 620 // LOCK HELD. Can be called with mInstallLock held. 621 @GuardedBy("mInstallLock") 622 final Installer mInstaller; 623 624 /** Directory where installed third-party apps stored */ 625 final File mAppInstallDir; 626 627 /** 628 * Directory to which applications installed internally have their 629 * 32 bit native libraries copied. 630 */ 631 private File mAppLib32InstallDir; 632 633 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 634 // apps. 635 final File mDrmAppPrivateInstallDir; 636 637 // ---------------------------------------------------------------- 638 639 // Lock for state used when installing and doing other long running 640 // operations. Methods that must be called with this lock held have 641 // the suffix "LI". 642 final Object mInstallLock = new Object(); 643 644 // ---------------------------------------------------------------- 645 646 // Keys are String (package name), values are Package. This also serves 647 // as the lock for the global state. Methods that must be called with 648 // this lock held have the prefix "LP". 649 @GuardedBy("mPackages") 650 final ArrayMap<String, PackageParser.Package> mPackages = 651 new ArrayMap<String, PackageParser.Package>(); 652 653 final ArrayMap<String, Set<String>> mKnownCodebase = 654 new ArrayMap<String, Set<String>>(); 655 656 // Keys are isolated uids and values are the uid of the application 657 // that created the isolated proccess. 658 @GuardedBy("mPackages") 659 final SparseIntArray mIsolatedOwners = new SparseIntArray(); 660 661 // List of APK paths to load for each user and package. This data is never 662 // persisted by the package manager. Instead, the overlay manager will 663 // ensure the data is up-to-date in runtime. 664 @GuardedBy("mPackages") 665 final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths = 666 new SparseArray<ArrayMap<String, ArrayList<String>>>(); 667 668 /** 669 * Tracks new system packages [received in an OTA] that we expect to 670 * find updated user-installed versions. Keys are package name, values 671 * are package location. 672 */ 673 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 674 /** 675 * Tracks high priority intent filters for protected actions. During boot, certain 676 * filter actions are protected and should never be allowed to have a high priority 677 * intent filter for them. However, there is one, and only one exception -- the 678 * setup wizard. It must be able to define a high priority intent filter for these 679 * actions to ensure there are no escapes from the wizard. We need to delay processing 680 * of these during boot as we need to look at all of the system packages in order 681 * to know which component is the setup wizard. 682 */ 683 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 684 /** 685 * Whether or not processing protected filters should be deferred. 686 */ 687 private boolean mDeferProtectedFilters = true; 688 689 /** 690 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 691 */ 692 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 693 /** 694 * Whether or not system app permissions should be promoted from install to runtime. 695 */ 696 boolean mPromoteSystemApps; 697 698 @GuardedBy("mPackages") 699 final Settings mSettings; 700 701 /** 702 * Set of package names that are currently "frozen", which means active 703 * surgery is being done on the code/data for that package. The platform 704 * will refuse to launch frozen packages to avoid race conditions. 705 * 706 * @see PackageFreezer 707 */ 708 @GuardedBy("mPackages") 709 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 710 711 final ProtectedPackages mProtectedPackages; 712 713 boolean mFirstBoot; 714 715 PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy; 716 717 // System configuration read by SystemConfig. 718 final int[] mGlobalGids; 719 final SparseArray<ArraySet<String>> mSystemPermissions; 720 @GuardedBy("mAvailableFeatures") 721 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 722 723 // If mac_permissions.xml was found for seinfo labeling. 724 boolean mFoundPolicyFile; 725 726 private final InstantAppRegistry mInstantAppRegistry; 727 728 @GuardedBy("mPackages") 729 int mChangedPackagesSequenceNumber; 730 /** 731 * List of changed [installed, removed or updated] packages. 732 * mapping from user id -> sequence number -> package name 733 */ 734 @GuardedBy("mPackages") 735 final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>(); 736 /** 737 * The sequence number of the last change to a package. 738 * mapping from user id -> package name -> sequence number 739 */ 740 @GuardedBy("mPackages") 741 final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>(); 742 743 final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() { 744 @Override public boolean hasFeature(String feature) { 745 return PackageManagerService.this.hasSystemFeature(feature, 0); 746 } 747 }; 748 749 public static final class SharedLibraryEntry { 750 public final String path; 751 public final String apk; 752 public final SharedLibraryInfo info; 753 754 SharedLibraryEntry(String _path, String _apk, String name, int version, int type, 755 String declaringPackageName, int declaringPackageVersionCode) { 756 path = _path; 757 apk = _apk; 758 info = new SharedLibraryInfo(name, version, type, new VersionedPackage( 759 declaringPackageName, declaringPackageVersionCode), null); 760 } 761 } 762 763 // Currently known shared libraries. 764 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>(); 765 final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage = 766 new ArrayMap<>(); 767 768 // All available activities, for your resolving pleasure. 769 final ActivityIntentResolver mActivities = 770 new ActivityIntentResolver(); 771 772 // All available receivers, for your resolving pleasure. 773 final ActivityIntentResolver mReceivers = 774 new ActivityIntentResolver(); 775 776 // All available services, for your resolving pleasure. 777 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 778 779 // All available providers, for your resolving pleasure. 780 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 781 782 // Mapping from provider base names (first directory in content URI codePath) 783 // to the provider information. 784 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 785 new ArrayMap<String, PackageParser.Provider>(); 786 787 // Mapping from instrumentation class names to info about them. 788 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 789 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 790 791 // Mapping from permission names to info about them. 792 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 793 new ArrayMap<String, PackageParser.PermissionGroup>(); 794 795 // Packages whose data we have transfered into another package, thus 796 // should no longer exist. 797 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 798 799 // Broadcast actions that are only available to the system. 800 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 801 802 /** List of packages waiting for verification. */ 803 final SparseArray<PackageVerificationState> mPendingVerification 804 = new SparseArray<PackageVerificationState>(); 805 806 /** Set of packages associated with each app op permission. */ 807 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 808 809 final PackageInstallerService mInstallerService; 810 811 private final PackageDexOptimizer mPackageDexOptimizer; 812 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package 813 // is used by other apps). 814 private final DexManager mDexManager; 815 816 private AtomicInteger mNextMoveId = new AtomicInteger(); 817 private final MoveCallbacks mMoveCallbacks; 818 819 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 820 821 // Cache of users who need badging. 822 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 823 824 /** Token for keys in mPendingVerification. */ 825 private int mPendingVerificationToken = 0; 826 827 volatile boolean mSystemReady; 828 volatile boolean mSafeMode; 829 volatile boolean mHasSystemUidErrors; 830 831 ApplicationInfo mAndroidApplication; 832 final ActivityInfo mResolveActivity = new ActivityInfo(); 833 final ResolveInfo mResolveInfo = new ResolveInfo(); 834 ComponentName mResolveComponentName; 835 PackageParser.Package mPlatformPackage; 836 ComponentName mCustomResolverComponentName; 837 838 boolean mResolverReplaced = false; 839 840 private final @Nullable ComponentName mIntentFilterVerifierComponent; 841 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 842 843 private int mIntentFilterVerificationToken = 0; 844 845 /** The service connection to the ephemeral resolver */ 846 final EphemeralResolverConnection mInstantAppResolverConnection; 847 848 /** Component used to install ephemeral applications */ 849 ComponentName mInstantAppInstallerComponent; 850 ActivityInfo mInstantAppInstallerActivity; 851 final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo(); 852 853 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 854 = new SparseArray<IntentFilterVerificationState>(); 855 856 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; 857 858 // List of packages names to keep cached, even if they are uninstalled for all users 859 private List<String> mKeepUninstalledPackages; 860 861 private UserManagerInternal mUserManagerInternal; 862 863 private DeviceIdleController.LocalService mDeviceIdleController; 864 865 private File mCacheDir; 866 867 private ArraySet<String> mPrivappPermissionsViolations; 868 869 private Future<?> mPrepareAppDataFuture; 870 871 private static class IFVerificationParams { 872 PackageParser.Package pkg; 873 boolean replacing; 874 int userId; 875 int verifierUid; 876 877 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 878 int _userId, int _verifierUid) { 879 pkg = _pkg; 880 replacing = _replacing; 881 userId = _userId; 882 replacing = _replacing; 883 verifierUid = _verifierUid; 884 } 885 } 886 887 private interface IntentFilterVerifier<T extends IntentFilter> { 888 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 889 T filter, String packageName); 890 void startVerifications(int userId); 891 void receiveVerificationResponse(int verificationId); 892 } 893 894 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 895 private Context mContext; 896 private ComponentName mIntentFilterVerifierComponent; 897 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 898 899 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 900 mContext = context; 901 mIntentFilterVerifierComponent = verifierComponent; 902 } 903 904 private String getDefaultScheme() { 905 return IntentFilter.SCHEME_HTTPS; 906 } 907 908 @Override 909 public void startVerifications(int userId) { 910 // Launch verifications requests 911 int count = mCurrentIntentFilterVerifications.size(); 912 for (int n=0; n<count; n++) { 913 int verificationId = mCurrentIntentFilterVerifications.get(n); 914 final IntentFilterVerificationState ivs = 915 mIntentFilterVerificationStates.get(verificationId); 916 917 String packageName = ivs.getPackageName(); 918 919 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 920 final int filterCount = filters.size(); 921 ArraySet<String> domainsSet = new ArraySet<>(); 922 for (int m=0; m<filterCount; m++) { 923 PackageParser.ActivityIntentInfo filter = filters.get(m); 924 domainsSet.addAll(filter.getHostsList()); 925 } 926 synchronized (mPackages) { 927 if (mSettings.createIntentFilterVerificationIfNeededLPw( 928 packageName, domainsSet) != null) { 929 scheduleWriteSettingsLocked(); 930 } 931 } 932 sendVerificationRequest(userId, verificationId, ivs); 933 } 934 mCurrentIntentFilterVerifications.clear(); 935 } 936 937 private void sendVerificationRequest(int userId, int verificationId, 938 IntentFilterVerificationState ivs) { 939 940 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 941 verificationIntent.putExtra( 942 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 943 verificationId); 944 verificationIntent.putExtra( 945 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 946 getDefaultScheme()); 947 verificationIntent.putExtra( 948 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 949 ivs.getHostsString()); 950 verificationIntent.putExtra( 951 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 952 ivs.getPackageName()); 953 verificationIntent.setComponent(mIntentFilterVerifierComponent); 954 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 955 956 UserHandle user = new UserHandle(userId); 957 mContext.sendBroadcastAsUser(verificationIntent, user); 958 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 959 "Sending IntentFilter verification broadcast"); 960 } 961 962 public void receiveVerificationResponse(int verificationId) { 963 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 964 965 final boolean verified = ivs.isVerified(); 966 967 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 968 final int count = filters.size(); 969 if (DEBUG_DOMAIN_VERIFICATION) { 970 Slog.i(TAG, "Received verification response " + verificationId 971 + " for " + count + " filters, verified=" + verified); 972 } 973 for (int n=0; n<count; n++) { 974 PackageParser.ActivityIntentInfo filter = filters.get(n); 975 filter.setVerified(verified); 976 977 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 978 + " verified with result:" + verified + " and hosts:" 979 + ivs.getHostsString()); 980 } 981 982 mIntentFilterVerificationStates.remove(verificationId); 983 984 final String packageName = ivs.getPackageName(); 985 IntentFilterVerificationInfo ivi = null; 986 987 synchronized (mPackages) { 988 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 989 } 990 if (ivi == null) { 991 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 992 + verificationId + " packageName:" + packageName); 993 return; 994 } 995 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 996 "Updating IntentFilterVerificationInfo for package " + packageName 997 +" verificationId:" + verificationId); 998 999 synchronized (mPackages) { 1000 if (verified) { 1001 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 1002 } else { 1003 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 1004 } 1005 scheduleWriteSettingsLocked(); 1006 1007 final int userId = ivs.getUserId(); 1008 if (userId != UserHandle.USER_ALL) { 1009 final int userStatus = 1010 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 1011 1012 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 1013 boolean needUpdate = false; 1014 1015 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 1016 // already been set by the User thru the Disambiguation dialog 1017 switch (userStatus) { 1018 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 1019 if (verified) { 1020 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 1021 } else { 1022 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 1023 } 1024 needUpdate = true; 1025 break; 1026 1027 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 1028 if (verified) { 1029 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 1030 needUpdate = true; 1031 } 1032 break; 1033 1034 default: 1035 // Nothing to do 1036 } 1037 1038 if (needUpdate) { 1039 mSettings.updateIntentFilterVerificationStatusLPw( 1040 packageName, updatedStatus, userId); 1041 scheduleWritePackageRestrictionsLocked(userId); 1042 } 1043 } 1044 } 1045 } 1046 1047 @Override 1048 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 1049 ActivityIntentInfo filter, String packageName) { 1050 if (!hasValidDomains(filter)) { 1051 return false; 1052 } 1053 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 1054 if (ivs == null) { 1055 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 1056 packageName); 1057 } 1058 if (DEBUG_DOMAIN_VERIFICATION) { 1059 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 1060 } 1061 ivs.addFilter(filter); 1062 return true; 1063 } 1064 1065 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 1066 int userId, int verificationId, String packageName) { 1067 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 1068 verifierUid, userId, packageName); 1069 ivs.setPendingState(); 1070 synchronized (mPackages) { 1071 mIntentFilterVerificationStates.append(verificationId, ivs); 1072 mCurrentIntentFilterVerifications.add(verificationId); 1073 } 1074 return ivs; 1075 } 1076 } 1077 1078 private static boolean hasValidDomains(ActivityIntentInfo filter) { 1079 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 1080 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 1081 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 1082 } 1083 1084 // Set of pending broadcasts for aggregating enable/disable of components. 1085 static class PendingPackageBroadcasts { 1086 // for each user id, a map of <package name -> components within that package> 1087 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 1088 1089 public PendingPackageBroadcasts() { 1090 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 1091 } 1092 1093 public ArrayList<String> get(int userId, String packageName) { 1094 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1095 return packages.get(packageName); 1096 } 1097 1098 public void put(int userId, String packageName, ArrayList<String> components) { 1099 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1100 packages.put(packageName, components); 1101 } 1102 1103 public void remove(int userId, String packageName) { 1104 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 1105 if (packages != null) { 1106 packages.remove(packageName); 1107 } 1108 } 1109 1110 public void remove(int userId) { 1111 mUidMap.remove(userId); 1112 } 1113 1114 public int userIdCount() { 1115 return mUidMap.size(); 1116 } 1117 1118 public int userIdAt(int n) { 1119 return mUidMap.keyAt(n); 1120 } 1121 1122 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 1123 return mUidMap.get(userId); 1124 } 1125 1126 public int size() { 1127 // total number of pending broadcast entries across all userIds 1128 int num = 0; 1129 for (int i = 0; i< mUidMap.size(); i++) { 1130 num += mUidMap.valueAt(i).size(); 1131 } 1132 return num; 1133 } 1134 1135 public void clear() { 1136 mUidMap.clear(); 1137 } 1138 1139 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1140 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1141 if (map == null) { 1142 map = new ArrayMap<String, ArrayList<String>>(); 1143 mUidMap.put(userId, map); 1144 } 1145 return map; 1146 } 1147 } 1148 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1149 1150 // Service Connection to remote media container service to copy 1151 // package uri's from external media onto secure containers 1152 // or internal storage. 1153 private IMediaContainerService mContainerService = null; 1154 1155 static final int SEND_PENDING_BROADCAST = 1; 1156 static final int MCS_BOUND = 3; 1157 static final int END_COPY = 4; 1158 static final int INIT_COPY = 5; 1159 static final int MCS_UNBIND = 6; 1160 static final int START_CLEANING_PACKAGE = 7; 1161 static final int FIND_INSTALL_LOC = 8; 1162 static final int POST_INSTALL = 9; 1163 static final int MCS_RECONNECT = 10; 1164 static final int MCS_GIVE_UP = 11; 1165 static final int UPDATED_MEDIA_STATUS = 12; 1166 static final int WRITE_SETTINGS = 13; 1167 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1168 static final int PACKAGE_VERIFIED = 15; 1169 static final int CHECK_PENDING_VERIFICATION = 16; 1170 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1171 static final int INTENT_FILTER_VERIFIED = 18; 1172 static final int WRITE_PACKAGE_LIST = 19; 1173 static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20; 1174 1175 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1176 1177 // Delay time in millisecs 1178 static final int BROADCAST_DELAY = 10 * 1000; 1179 1180 static UserManagerService sUserManager; 1181 1182 // Stores a list of users whose package restrictions file needs to be updated 1183 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1184 1185 final private DefaultContainerConnection mDefContainerConn = 1186 new DefaultContainerConnection(); 1187 class DefaultContainerConnection implements ServiceConnection { 1188 public void onServiceConnected(ComponentName name, IBinder service) { 1189 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1190 final IMediaContainerService imcs = IMediaContainerService.Stub 1191 .asInterface(Binder.allowBlocking(service)); 1192 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1193 } 1194 1195 public void onServiceDisconnected(ComponentName name) { 1196 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1197 } 1198 } 1199 1200 // Recordkeeping of restore-after-install operations that are currently in flight 1201 // between the Package Manager and the Backup Manager 1202 static class PostInstallData { 1203 public InstallArgs args; 1204 public PackageInstalledInfo res; 1205 1206 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1207 args = _a; 1208 res = _r; 1209 } 1210 } 1211 1212 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1213 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1214 1215 // XML tags for backup/restore of various bits of state 1216 private static final String TAG_PREFERRED_BACKUP = "pa"; 1217 private static final String TAG_DEFAULT_APPS = "da"; 1218 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1219 1220 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1221 private static final String TAG_ALL_GRANTS = "rt-grants"; 1222 private static final String TAG_GRANT = "grant"; 1223 private static final String ATTR_PACKAGE_NAME = "pkg"; 1224 1225 private static final String TAG_PERMISSION = "perm"; 1226 private static final String ATTR_PERMISSION_NAME = "name"; 1227 private static final String ATTR_IS_GRANTED = "g"; 1228 private static final String ATTR_USER_SET = "set"; 1229 private static final String ATTR_USER_FIXED = "fixed"; 1230 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1231 1232 // System/policy permission grants are not backed up 1233 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1234 FLAG_PERMISSION_POLICY_FIXED 1235 | FLAG_PERMISSION_SYSTEM_FIXED 1236 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1237 1238 // And we back up these user-adjusted states 1239 private static final int USER_RUNTIME_GRANT_MASK = 1240 FLAG_PERMISSION_USER_SET 1241 | FLAG_PERMISSION_USER_FIXED 1242 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1243 1244 final @Nullable String mRequiredVerifierPackage; 1245 final @NonNull String mRequiredInstallerPackage; 1246 final @NonNull String mRequiredUninstallerPackage; 1247 final @Nullable String mSetupWizardPackage; 1248 final @Nullable String mStorageManagerPackage; 1249 final @NonNull String mServicesSystemSharedLibraryPackageName; 1250 final @NonNull String mSharedSystemSharedLibraryPackageName; 1251 1252 final boolean mPermissionReviewRequired; 1253 1254 private final PackageUsage mPackageUsage = new PackageUsage(); 1255 private final CompilerStats mCompilerStats = new CompilerStats(); 1256 1257 class PackageHandler extends Handler { 1258 private boolean mBound = false; 1259 final ArrayList<HandlerParams> mPendingInstalls = 1260 new ArrayList<HandlerParams>(); 1261 1262 private boolean connectToService() { 1263 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1264 " DefaultContainerService"); 1265 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1266 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1267 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1268 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1269 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1270 mBound = true; 1271 return true; 1272 } 1273 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1274 return false; 1275 } 1276 1277 private void disconnectService() { 1278 mContainerService = null; 1279 mBound = false; 1280 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1281 mContext.unbindService(mDefContainerConn); 1282 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1283 } 1284 1285 PackageHandler(Looper looper) { 1286 super(looper); 1287 } 1288 1289 public void handleMessage(Message msg) { 1290 try { 1291 doHandleMessage(msg); 1292 } finally { 1293 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1294 } 1295 } 1296 1297 void doHandleMessage(Message msg) { 1298 switch (msg.what) { 1299 case INIT_COPY: { 1300 HandlerParams params = (HandlerParams) msg.obj; 1301 int idx = mPendingInstalls.size(); 1302 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1303 // If a bind was already initiated we dont really 1304 // need to do anything. The pending install 1305 // will be processed later on. 1306 if (!mBound) { 1307 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1308 System.identityHashCode(mHandler)); 1309 // If this is the only one pending we might 1310 // have to bind to the service again. 1311 if (!connectToService()) { 1312 Slog.e(TAG, "Failed to bind to media container service"); 1313 params.serviceError(); 1314 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1315 System.identityHashCode(mHandler)); 1316 if (params.traceMethod != null) { 1317 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1318 params.traceCookie); 1319 } 1320 return; 1321 } else { 1322 // Once we bind to the service, the first 1323 // pending request will be processed. 1324 mPendingInstalls.add(idx, params); 1325 } 1326 } else { 1327 mPendingInstalls.add(idx, params); 1328 // Already bound to the service. Just make 1329 // sure we trigger off processing the first request. 1330 if (idx == 0) { 1331 mHandler.sendEmptyMessage(MCS_BOUND); 1332 } 1333 } 1334 break; 1335 } 1336 case MCS_BOUND: { 1337 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1338 if (msg.obj != null) { 1339 mContainerService = (IMediaContainerService) msg.obj; 1340 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1341 System.identityHashCode(mHandler)); 1342 } 1343 if (mContainerService == null) { 1344 if (!mBound) { 1345 // Something seriously wrong since we are not bound and we are not 1346 // waiting for connection. Bail out. 1347 Slog.e(TAG, "Cannot bind to media container service"); 1348 for (HandlerParams params : mPendingInstalls) { 1349 // Indicate service bind error 1350 params.serviceError(); 1351 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1352 System.identityHashCode(params)); 1353 if (params.traceMethod != null) { 1354 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1355 params.traceMethod, params.traceCookie); 1356 } 1357 return; 1358 } 1359 mPendingInstalls.clear(); 1360 } else { 1361 Slog.w(TAG, "Waiting to connect to media container service"); 1362 } 1363 } else if (mPendingInstalls.size() > 0) { 1364 HandlerParams params = mPendingInstalls.get(0); 1365 if (params != null) { 1366 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1367 System.identityHashCode(params)); 1368 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1369 if (params.startCopy()) { 1370 // We are done... look for more work or to 1371 // go idle. 1372 if (DEBUG_SD_INSTALL) Log.i(TAG, 1373 "Checking for more work or unbind..."); 1374 // Delete pending install 1375 if (mPendingInstalls.size() > 0) { 1376 mPendingInstalls.remove(0); 1377 } 1378 if (mPendingInstalls.size() == 0) { 1379 if (mBound) { 1380 if (DEBUG_SD_INSTALL) Log.i(TAG, 1381 "Posting delayed MCS_UNBIND"); 1382 removeMessages(MCS_UNBIND); 1383 Message ubmsg = obtainMessage(MCS_UNBIND); 1384 // Unbind after a little delay, to avoid 1385 // continual thrashing. 1386 sendMessageDelayed(ubmsg, 10000); 1387 } 1388 } else { 1389 // There are more pending requests in queue. 1390 // Just post MCS_BOUND message to trigger processing 1391 // of next pending install. 1392 if (DEBUG_SD_INSTALL) Log.i(TAG, 1393 "Posting MCS_BOUND for next work"); 1394 mHandler.sendEmptyMessage(MCS_BOUND); 1395 } 1396 } 1397 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1398 } 1399 } else { 1400 // Should never happen ideally. 1401 Slog.w(TAG, "Empty queue"); 1402 } 1403 break; 1404 } 1405 case MCS_RECONNECT: { 1406 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1407 if (mPendingInstalls.size() > 0) { 1408 if (mBound) { 1409 disconnectService(); 1410 } 1411 if (!connectToService()) { 1412 Slog.e(TAG, "Failed to bind to media container service"); 1413 for (HandlerParams params : mPendingInstalls) { 1414 // Indicate service bind error 1415 params.serviceError(); 1416 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1417 System.identityHashCode(params)); 1418 } 1419 mPendingInstalls.clear(); 1420 } 1421 } 1422 break; 1423 } 1424 case MCS_UNBIND: { 1425 // If there is no actual work left, then time to unbind. 1426 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1427 1428 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1429 if (mBound) { 1430 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1431 1432 disconnectService(); 1433 } 1434 } else if (mPendingInstalls.size() > 0) { 1435 // There are more pending requests in queue. 1436 // Just post MCS_BOUND message to trigger processing 1437 // of next pending install. 1438 mHandler.sendEmptyMessage(MCS_BOUND); 1439 } 1440 1441 break; 1442 } 1443 case MCS_GIVE_UP: { 1444 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1445 HandlerParams params = mPendingInstalls.remove(0); 1446 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1447 System.identityHashCode(params)); 1448 break; 1449 } 1450 case SEND_PENDING_BROADCAST: { 1451 String packages[]; 1452 ArrayList<String> components[]; 1453 int size = 0; 1454 int uids[]; 1455 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1456 synchronized (mPackages) { 1457 if (mPendingBroadcasts == null) { 1458 return; 1459 } 1460 size = mPendingBroadcasts.size(); 1461 if (size <= 0) { 1462 // Nothing to be done. Just return 1463 return; 1464 } 1465 packages = new String[size]; 1466 components = new ArrayList[size]; 1467 uids = new int[size]; 1468 int i = 0; // filling out the above arrays 1469 1470 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1471 int packageUserId = mPendingBroadcasts.userIdAt(n); 1472 Iterator<Map.Entry<String, ArrayList<String>>> it 1473 = mPendingBroadcasts.packagesForUserId(packageUserId) 1474 .entrySet().iterator(); 1475 while (it.hasNext() && i < size) { 1476 Map.Entry<String, ArrayList<String>> ent = it.next(); 1477 packages[i] = ent.getKey(); 1478 components[i] = ent.getValue(); 1479 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1480 uids[i] = (ps != null) 1481 ? UserHandle.getUid(packageUserId, ps.appId) 1482 : -1; 1483 i++; 1484 } 1485 } 1486 size = i; 1487 mPendingBroadcasts.clear(); 1488 } 1489 // Send broadcasts 1490 for (int i = 0; i < size; i++) { 1491 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1492 } 1493 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1494 break; 1495 } 1496 case START_CLEANING_PACKAGE: { 1497 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1498 final String packageName = (String)msg.obj; 1499 final int userId = msg.arg1; 1500 final boolean andCode = msg.arg2 != 0; 1501 synchronized (mPackages) { 1502 if (userId == UserHandle.USER_ALL) { 1503 int[] users = sUserManager.getUserIds(); 1504 for (int user : users) { 1505 mSettings.addPackageToCleanLPw( 1506 new PackageCleanItem(user, packageName, andCode)); 1507 } 1508 } else { 1509 mSettings.addPackageToCleanLPw( 1510 new PackageCleanItem(userId, packageName, andCode)); 1511 } 1512 } 1513 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1514 startCleaningPackages(); 1515 } break; 1516 case POST_INSTALL: { 1517 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1518 1519 PostInstallData data = mRunningInstalls.get(msg.arg1); 1520 final boolean didRestore = (msg.arg2 != 0); 1521 mRunningInstalls.delete(msg.arg1); 1522 1523 if (data != null) { 1524 InstallArgs args = data.args; 1525 PackageInstalledInfo parentRes = data.res; 1526 1527 final boolean grantPermissions = (args.installFlags 1528 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1529 final boolean killApp = (args.installFlags 1530 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1531 final String[] grantedPermissions = args.installGrantPermissions; 1532 1533 // Handle the parent package 1534 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1535 grantedPermissions, didRestore, args.installerPackageName, 1536 args.observer); 1537 1538 // Handle the child packages 1539 final int childCount = (parentRes.addedChildPackages != null) 1540 ? parentRes.addedChildPackages.size() : 0; 1541 for (int i = 0; i < childCount; i++) { 1542 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1543 handlePackagePostInstall(childRes, grantPermissions, killApp, 1544 grantedPermissions, false, args.installerPackageName, 1545 args.observer); 1546 } 1547 1548 // Log tracing if needed 1549 if (args.traceMethod != null) { 1550 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1551 args.traceCookie); 1552 } 1553 } else { 1554 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1555 } 1556 1557 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1558 } break; 1559 case UPDATED_MEDIA_STATUS: { 1560 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1561 boolean reportStatus = msg.arg1 == 1; 1562 boolean doGc = msg.arg2 == 1; 1563 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1564 if (doGc) { 1565 // Force a gc to clear up stale containers. 1566 Runtime.getRuntime().gc(); 1567 } 1568 if (msg.obj != null) { 1569 @SuppressWarnings("unchecked") 1570 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1571 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1572 // Unload containers 1573 unloadAllContainers(args); 1574 } 1575 if (reportStatus) { 1576 try { 1577 if (DEBUG_SD_INSTALL) Log.i(TAG, 1578 "Invoking StorageManagerService call back"); 1579 PackageHelper.getStorageManager().finishMediaUpdate(); 1580 } catch (RemoteException e) { 1581 Log.e(TAG, "StorageManagerService not running?"); 1582 } 1583 } 1584 } break; 1585 case WRITE_SETTINGS: { 1586 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1587 synchronized (mPackages) { 1588 removeMessages(WRITE_SETTINGS); 1589 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1590 mSettings.writeLPr(); 1591 mDirtyUsers.clear(); 1592 } 1593 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1594 } break; 1595 case WRITE_PACKAGE_RESTRICTIONS: { 1596 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1597 synchronized (mPackages) { 1598 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1599 for (int userId : mDirtyUsers) { 1600 mSettings.writePackageRestrictionsLPr(userId); 1601 } 1602 mDirtyUsers.clear(); 1603 } 1604 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1605 } break; 1606 case WRITE_PACKAGE_LIST: { 1607 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1608 synchronized (mPackages) { 1609 removeMessages(WRITE_PACKAGE_LIST); 1610 mSettings.writePackageListLPr(msg.arg1); 1611 } 1612 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1613 } break; 1614 case CHECK_PENDING_VERIFICATION: { 1615 final int verificationId = msg.arg1; 1616 final PackageVerificationState state = mPendingVerification.get(verificationId); 1617 1618 if ((state != null) && !state.timeoutExtended()) { 1619 final InstallArgs args = state.getInstallArgs(); 1620 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1621 1622 Slog.i(TAG, "Verification timed out for " + originUri); 1623 mPendingVerification.remove(verificationId); 1624 1625 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1626 1627 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1628 Slog.i(TAG, "Continuing with installation of " + originUri); 1629 state.setVerifierResponse(Binder.getCallingUid(), 1630 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1631 broadcastPackageVerified(verificationId, originUri, 1632 PackageManager.VERIFICATION_ALLOW, 1633 state.getInstallArgs().getUser()); 1634 try { 1635 ret = args.copyApk(mContainerService, true); 1636 } catch (RemoteException e) { 1637 Slog.e(TAG, "Could not contact the ContainerService"); 1638 } 1639 } else { 1640 broadcastPackageVerified(verificationId, originUri, 1641 PackageManager.VERIFICATION_REJECT, 1642 state.getInstallArgs().getUser()); 1643 } 1644 1645 Trace.asyncTraceEnd( 1646 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1647 1648 processPendingInstall(args, ret); 1649 mHandler.sendEmptyMessage(MCS_UNBIND); 1650 } 1651 break; 1652 } 1653 case PACKAGE_VERIFIED: { 1654 final int verificationId = msg.arg1; 1655 1656 final PackageVerificationState state = mPendingVerification.get(verificationId); 1657 if (state == null) { 1658 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1659 break; 1660 } 1661 1662 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1663 1664 state.setVerifierResponse(response.callerUid, response.code); 1665 1666 if (state.isVerificationComplete()) { 1667 mPendingVerification.remove(verificationId); 1668 1669 final InstallArgs args = state.getInstallArgs(); 1670 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1671 1672 int ret; 1673 if (state.isInstallAllowed()) { 1674 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1675 broadcastPackageVerified(verificationId, originUri, 1676 response.code, state.getInstallArgs().getUser()); 1677 try { 1678 ret = args.copyApk(mContainerService, true); 1679 } catch (RemoteException e) { 1680 Slog.e(TAG, "Could not contact the ContainerService"); 1681 } 1682 } else { 1683 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1684 } 1685 1686 Trace.asyncTraceEnd( 1687 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1688 1689 processPendingInstall(args, ret); 1690 mHandler.sendEmptyMessage(MCS_UNBIND); 1691 } 1692 1693 break; 1694 } 1695 case START_INTENT_FILTER_VERIFICATIONS: { 1696 IFVerificationParams params = (IFVerificationParams) msg.obj; 1697 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1698 params.replacing, params.pkg); 1699 break; 1700 } 1701 case INTENT_FILTER_VERIFIED: { 1702 final int verificationId = msg.arg1; 1703 1704 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1705 verificationId); 1706 if (state == null) { 1707 Slog.w(TAG, "Invalid IntentFilter verification token " 1708 + verificationId + " received"); 1709 break; 1710 } 1711 1712 final int userId = state.getUserId(); 1713 1714 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1715 "Processing IntentFilter verification with token:" 1716 + verificationId + " and userId:" + userId); 1717 1718 final IntentFilterVerificationResponse response = 1719 (IntentFilterVerificationResponse) msg.obj; 1720 1721 state.setVerifierResponse(response.callerUid, response.code); 1722 1723 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1724 "IntentFilter verification with token:" + verificationId 1725 + " and userId:" + userId 1726 + " is settings verifier response with response code:" 1727 + response.code); 1728 1729 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1730 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1731 + response.getFailedDomainsString()); 1732 } 1733 1734 if (state.isVerificationComplete()) { 1735 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1736 } else { 1737 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1738 "IntentFilter verification with token:" + verificationId 1739 + " was not said to be complete"); 1740 } 1741 1742 break; 1743 } 1744 case INSTANT_APP_RESOLUTION_PHASE_TWO: { 1745 InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext, 1746 mInstantAppResolverConnection, 1747 (InstantAppRequest) msg.obj, 1748 mInstantAppInstallerActivity, 1749 mHandler); 1750 } 1751 } 1752 } 1753 } 1754 1755 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1756 boolean killApp, String[] grantedPermissions, 1757 boolean launchedForRestore, String installerPackage, 1758 IPackageInstallObserver2 installObserver) { 1759 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1760 // Send the removed broadcasts 1761 if (res.removedInfo != null) { 1762 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1763 } 1764 1765 // Now that we successfully installed the package, grant runtime 1766 // permissions if requested before broadcasting the install. Also 1767 // for legacy apps in permission review mode we clear the permission 1768 // review flag which is used to emulate runtime permissions for 1769 // legacy apps. 1770 if (grantPermissions) { 1771 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1772 } 1773 1774 final boolean update = res.removedInfo != null 1775 && res.removedInfo.removedPackage != null; 1776 1777 // If this is the first time we have child packages for a disabled privileged 1778 // app that had no children, we grant requested runtime permissions to the new 1779 // children if the parent on the system image had them already granted. 1780 if (res.pkg.parentPackage != null) { 1781 synchronized (mPackages) { 1782 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1783 } 1784 } 1785 1786 synchronized (mPackages) { 1787 mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers); 1788 } 1789 1790 final String packageName = res.pkg.applicationInfo.packageName; 1791 1792 // Determine the set of users who are adding this package for 1793 // the first time vs. those who are seeing an update. 1794 int[] firstUsers = EMPTY_INT_ARRAY; 1795 int[] updateUsers = EMPTY_INT_ARRAY; 1796 final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0; 1797 final PackageSetting ps = (PackageSetting) res.pkg.mExtras; 1798 for (int newUser : res.newUsers) { 1799 if (ps.getInstantApp(newUser)) { 1800 continue; 1801 } 1802 if (allNewUsers) { 1803 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1804 continue; 1805 } 1806 boolean isNew = true; 1807 for (int origUser : res.origUsers) { 1808 if (origUser == newUser) { 1809 isNew = false; 1810 break; 1811 } 1812 } 1813 if (isNew) { 1814 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1815 } else { 1816 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1817 } 1818 } 1819 1820 // Send installed broadcasts if the package is not a static shared lib. 1821 if (res.pkg.staticSharedLibName == null) { 1822 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1823 1824 // Send added for users that see the package for the first time 1825 // sendPackageAddedForNewUsers also deals with system apps 1826 int appId = UserHandle.getAppId(res.uid); 1827 boolean isSystem = res.pkg.applicationInfo.isSystemApp(); 1828 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers); 1829 1830 // Send added for users that don't see the package for the first time 1831 Bundle extras = new Bundle(1); 1832 extras.putInt(Intent.EXTRA_UID, res.uid); 1833 if (update) { 1834 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1835 } 1836 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1837 extras, 0 /*flags*/, null /*targetPackage*/, 1838 null /*finishedReceiver*/, updateUsers); 1839 1840 // Send replaced for users that don't see the package for the first time 1841 if (update) { 1842 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1843 packageName, extras, 0 /*flags*/, 1844 null /*targetPackage*/, null /*finishedReceiver*/, 1845 updateUsers); 1846 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1847 null /*package*/, null /*extras*/, 0 /*flags*/, 1848 packageName /*targetPackage*/, 1849 null /*finishedReceiver*/, updateUsers); 1850 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1851 // First-install and we did a restore, so we're responsible for the 1852 // first-launch broadcast. 1853 if (DEBUG_BACKUP) { 1854 Slog.i(TAG, "Post-restore of " + packageName 1855 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1856 } 1857 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1858 } 1859 1860 // Send broadcast package appeared if forward locked/external for all users 1861 // treat asec-hosted packages like removable media on upgrade 1862 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1863 if (DEBUG_INSTALL) { 1864 Slog.i(TAG, "upgrading pkg " + res.pkg 1865 + " is ASEC-hosted -> AVAILABLE"); 1866 } 1867 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1868 ArrayList<String> pkgList = new ArrayList<>(1); 1869 pkgList.add(packageName); 1870 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1871 } 1872 } 1873 1874 // Work that needs to happen on first install within each user 1875 if (firstUsers != null && firstUsers.length > 0) { 1876 synchronized (mPackages) { 1877 for (int userId : firstUsers) { 1878 // If this app is a browser and it's newly-installed for some 1879 // users, clear any default-browser state in those users. The 1880 // app's nature doesn't depend on the user, so we can just check 1881 // its browser nature in any user and generalize. 1882 if (packageIsBrowser(packageName, userId)) { 1883 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1884 } 1885 1886 // We may also need to apply pending (restored) runtime 1887 // permission grants within these users. 1888 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1889 } 1890 } 1891 } 1892 1893 // Log current value of "unknown sources" setting 1894 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1895 getUnknownSourcesSettings()); 1896 1897 // Force a gc to clear up things 1898 Runtime.getRuntime().gc(); 1899 1900 // Remove the replaced package's older resources safely now 1901 // We delete after a gc for applications on sdcard. 1902 if (res.removedInfo != null && res.removedInfo.args != null) { 1903 synchronized (mInstallLock) { 1904 res.removedInfo.args.doPostDeleteLI(true); 1905 } 1906 } 1907 1908 // Notify DexManager that the package was installed for new users. 1909 // The updated users should already be indexed and the package code paths 1910 // should not change. 1911 // Don't notify the manager for ephemeral apps as they are not expected to 1912 // survive long enough to benefit of background optimizations. 1913 for (int userId : firstUsers) { 1914 PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId); 1915 mDexManager.notifyPackageInstalled(info, userId); 1916 } 1917 } 1918 1919 // If someone is watching installs - notify them 1920 if (installObserver != null) { 1921 try { 1922 Bundle extras = extrasForInstallResult(res); 1923 installObserver.onPackageInstalled(res.name, res.returnCode, 1924 res.returnMsg, extras); 1925 } catch (RemoteException e) { 1926 Slog.i(TAG, "Observer no longer exists."); 1927 } 1928 } 1929 } 1930 1931 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1932 PackageParser.Package pkg) { 1933 if (pkg.parentPackage == null) { 1934 return; 1935 } 1936 if (pkg.requestedPermissions == null) { 1937 return; 1938 } 1939 final PackageSetting disabledSysParentPs = mSettings 1940 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1941 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1942 || !disabledSysParentPs.isPrivileged() 1943 || (disabledSysParentPs.childPackageNames != null 1944 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1945 return; 1946 } 1947 final int[] allUserIds = sUserManager.getUserIds(); 1948 final int permCount = pkg.requestedPermissions.size(); 1949 for (int i = 0; i < permCount; i++) { 1950 String permission = pkg.requestedPermissions.get(i); 1951 BasePermission bp = mSettings.mPermissions.get(permission); 1952 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1953 continue; 1954 } 1955 for (int userId : allUserIds) { 1956 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1957 permission, userId)) { 1958 grantRuntimePermission(pkg.packageName, permission, userId); 1959 } 1960 } 1961 } 1962 } 1963 1964 private StorageEventListener mStorageListener = new StorageEventListener() { 1965 @Override 1966 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1967 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1968 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1969 final String volumeUuid = vol.getFsUuid(); 1970 1971 // Clean up any users or apps that were removed or recreated 1972 // while this volume was missing 1973 sUserManager.reconcileUsers(volumeUuid); 1974 reconcileApps(volumeUuid); 1975 1976 // Clean up any install sessions that expired or were 1977 // cancelled while this volume was missing 1978 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1979 1980 loadPrivatePackages(vol); 1981 1982 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1983 unloadPrivatePackages(vol); 1984 } 1985 } 1986 1987 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1988 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1989 updateExternalMediaStatus(true, false); 1990 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1991 updateExternalMediaStatus(false, false); 1992 } 1993 } 1994 } 1995 1996 @Override 1997 public void onVolumeForgotten(String fsUuid) { 1998 if (TextUtils.isEmpty(fsUuid)) { 1999 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 2000 return; 2001 } 2002 2003 // Remove any apps installed on the forgotten volume 2004 synchronized (mPackages) { 2005 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 2006 for (PackageSetting ps : packages) { 2007 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 2008 deletePackageVersioned(new VersionedPackage(ps.name, 2009 PackageManager.VERSION_CODE_HIGHEST), 2010 new LegacyPackageDeleteObserver(null).getBinder(), 2011 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 2012 // Try very hard to release any references to this package 2013 // so we don't risk the system server being killed due to 2014 // open FDs 2015 AttributeCache.instance().removePackage(ps.name); 2016 } 2017 2018 mSettings.onVolumeForgotten(fsUuid); 2019 mSettings.writeLPr(); 2020 } 2021 } 2022 }; 2023 2024 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 2025 String[] grantedPermissions) { 2026 for (int userId : userIds) { 2027 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 2028 } 2029 } 2030 2031 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 2032 String[] grantedPermissions) { 2033 SettingBase sb = (SettingBase) pkg.mExtras; 2034 if (sb == null) { 2035 return; 2036 } 2037 2038 PermissionsState permissionsState = sb.getPermissionsState(); 2039 2040 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 2041 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 2042 2043 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 2044 >= Build.VERSION_CODES.M; 2045 2046 final boolean instantApp = isInstantApp(pkg.packageName, userId); 2047 2048 for (String permission : pkg.requestedPermissions) { 2049 final BasePermission bp; 2050 synchronized (mPackages) { 2051 bp = mSettings.mPermissions.get(permission); 2052 } 2053 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 2054 && (!instantApp || bp.isInstant()) 2055 && (grantedPermissions == null 2056 || ArrayUtils.contains(grantedPermissions, permission))) { 2057 final int flags = permissionsState.getPermissionFlags(permission, userId); 2058 if (supportsRuntimePermissions) { 2059 // Installer cannot change immutable permissions. 2060 if ((flags & immutableFlags) == 0) { 2061 grantRuntimePermission(pkg.packageName, permission, userId); 2062 } 2063 } else if (mPermissionReviewRequired) { 2064 // In permission review mode we clear the review flag when we 2065 // are asked to install the app with all permissions granted. 2066 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 2067 updatePermissionFlags(permission, pkg.packageName, 2068 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId); 2069 } 2070 } 2071 } 2072 } 2073 } 2074 2075 Bundle extrasForInstallResult(PackageInstalledInfo res) { 2076 Bundle extras = null; 2077 switch (res.returnCode) { 2078 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 2079 extras = new Bundle(); 2080 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 2081 res.origPermission); 2082 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 2083 res.origPackage); 2084 break; 2085 } 2086 case PackageManager.INSTALL_SUCCEEDED: { 2087 extras = new Bundle(); 2088 extras.putBoolean(Intent.EXTRA_REPLACING, 2089 res.removedInfo != null && res.removedInfo.removedPackage != null); 2090 break; 2091 } 2092 } 2093 return extras; 2094 } 2095 2096 void scheduleWriteSettingsLocked() { 2097 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 2098 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 2099 } 2100 } 2101 2102 void scheduleWritePackageListLocked(int userId) { 2103 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 2104 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 2105 msg.arg1 = userId; 2106 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 2107 } 2108 } 2109 2110 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 2111 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 2112 scheduleWritePackageRestrictionsLocked(userId); 2113 } 2114 2115 void scheduleWritePackageRestrictionsLocked(int userId) { 2116 final int[] userIds = (userId == UserHandle.USER_ALL) 2117 ? sUserManager.getUserIds() : new int[]{userId}; 2118 for (int nextUserId : userIds) { 2119 if (!sUserManager.exists(nextUserId)) return; 2120 mDirtyUsers.add(nextUserId); 2121 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 2122 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 2123 } 2124 } 2125 } 2126 2127 public static PackageManagerService main(Context context, Installer installer, 2128 boolean factoryTest, boolean onlyCore) { 2129 // Self-check for initial settings. 2130 PackageManagerServiceCompilerMapping.checkProperties(); 2131 2132 PackageManagerService m = new PackageManagerService(context, installer, 2133 factoryTest, onlyCore); 2134 m.enableSystemUserPackages(); 2135 ServiceManager.addService("package", m); 2136 return m; 2137 } 2138 2139 private void enableSystemUserPackages() { 2140 if (!UserManager.isSplitSystemUser()) { 2141 return; 2142 } 2143 // For system user, enable apps based on the following conditions: 2144 // - app is whitelisted or belong to one of these groups: 2145 // -- system app which has no launcher icons 2146 // -- system app which has INTERACT_ACROSS_USERS permission 2147 // -- system IME app 2148 // - app is not in the blacklist 2149 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 2150 Set<String> enableApps = new ArraySet<>(); 2151 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 2152 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 2153 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 2154 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2155 enableApps.addAll(wlApps); 2156 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2157 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2158 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2159 enableApps.removeAll(blApps); 2160 Log.i(TAG, "Applications installed for system user: " + enableApps); 2161 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2162 UserHandle.SYSTEM); 2163 final int allAppsSize = allAps.size(); 2164 synchronized (mPackages) { 2165 for (int i = 0; i < allAppsSize; i++) { 2166 String pName = allAps.get(i); 2167 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2168 // Should not happen, but we shouldn't be failing if it does 2169 if (pkgSetting == null) { 2170 continue; 2171 } 2172 boolean install = enableApps.contains(pName); 2173 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2174 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2175 + " for system user"); 2176 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2177 } 2178 } 2179 scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM); 2180 } 2181 } 2182 2183 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2184 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2185 Context.DISPLAY_SERVICE); 2186 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2187 } 2188 2189 /** 2190 * Requests that files preopted on a secondary system partition be copied to the data partition 2191 * if possible. Note that the actual copying of the files is accomplished by init for security 2192 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2193 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2194 */ 2195 private static void requestCopyPreoptedFiles() { 2196 final int WAIT_TIME_MS = 100; 2197 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2198 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2199 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2200 // We will wait for up to 100 seconds. 2201 final long timeStart = SystemClock.uptimeMillis(); 2202 final long timeEnd = timeStart + 100 * 1000; 2203 long timeNow = timeStart; 2204 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2205 try { 2206 Thread.sleep(WAIT_TIME_MS); 2207 } catch (InterruptedException e) { 2208 // Do nothing 2209 } 2210 timeNow = SystemClock.uptimeMillis(); 2211 if (timeNow > timeEnd) { 2212 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2213 Slog.wtf(TAG, "cppreopt did not finish!"); 2214 break; 2215 } 2216 } 2217 2218 Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms"); 2219 } 2220 } 2221 2222 public PackageManagerService(Context context, Installer installer, 2223 boolean factoryTest, boolean onlyCore) { 2224 LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES); 2225 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager"); 2226 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2227 SystemClock.uptimeMillis()); 2228 2229 if (mSdkVersion <= 0) { 2230 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2231 } 2232 2233 mContext = context; 2234 2235 mPermissionReviewRequired = context.getResources().getBoolean( 2236 R.bool.config_permissionReviewRequired); 2237 2238 mFactoryTest = factoryTest; 2239 mOnlyCore = onlyCore; 2240 mMetrics = new DisplayMetrics(); 2241 mSettings = new Settings(mPackages); 2242 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2243 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2244 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2245 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2246 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2247 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2248 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2249 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2250 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2251 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2252 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2253 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2254 2255 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2256 if (separateProcesses != null && separateProcesses.length() > 0) { 2257 if ("*".equals(separateProcesses)) { 2258 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2259 mSeparateProcesses = null; 2260 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2261 } else { 2262 mDefParseFlags = 0; 2263 mSeparateProcesses = separateProcesses.split(","); 2264 Slog.w(TAG, "Running with debug.separate_processes: " 2265 + separateProcesses); 2266 } 2267 } else { 2268 mDefParseFlags = 0; 2269 mSeparateProcesses = null; 2270 } 2271 2272 mInstaller = installer; 2273 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2274 "*dexopt*"); 2275 mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock); 2276 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2277 2278 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2279 FgThread.get().getLooper()); 2280 2281 getDefaultDisplayMetrics(context, mMetrics); 2282 2283 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config"); 2284 SystemConfig systemConfig = SystemConfig.getInstance(); 2285 mGlobalGids = systemConfig.getGlobalGids(); 2286 mSystemPermissions = systemConfig.getSystemPermissions(); 2287 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2288 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2289 2290 mProtectedPackages = new ProtectedPackages(mContext); 2291 2292 synchronized (mInstallLock) { 2293 // writer 2294 synchronized (mPackages) { 2295 mHandlerThread = new ServiceThread(TAG, 2296 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2297 mHandlerThread.start(); 2298 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2299 mProcessLoggingHandler = new ProcessLoggingHandler(); 2300 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2301 2302 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 2303 mInstantAppRegistry = new InstantAppRegistry(this); 2304 2305 File dataDir = Environment.getDataDirectory(); 2306 mAppInstallDir = new File(dataDir, "app"); 2307 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2308 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2309 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2310 sUserManager = new UserManagerService(context, this, 2311 new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages); 2312 2313 // Propagate permission configuration in to package manager. 2314 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2315 = systemConfig.getPermissions(); 2316 for (int i=0; i<permConfig.size(); i++) { 2317 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2318 BasePermission bp = mSettings.mPermissions.get(perm.name); 2319 if (bp == null) { 2320 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2321 mSettings.mPermissions.put(perm.name, bp); 2322 } 2323 if (perm.gids != null) { 2324 bp.setGids(perm.gids, perm.perUser); 2325 } 2326 } 2327 2328 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2329 final int builtInLibCount = libConfig.size(); 2330 for (int i = 0; i < builtInLibCount; i++) { 2331 String name = libConfig.keyAt(i); 2332 String path = libConfig.valueAt(i); 2333 addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED, 2334 SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0); 2335 } 2336 2337 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2338 2339 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings"); 2340 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2341 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2342 2343 // Clean up orphaned packages for which the code path doesn't exist 2344 // and they are an update to a system app - caused by bug/32321269 2345 final int packageSettingCount = mSettings.mPackages.size(); 2346 for (int i = packageSettingCount - 1; i >= 0; i--) { 2347 PackageSetting ps = mSettings.mPackages.valueAt(i); 2348 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists()) 2349 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) { 2350 mSettings.mPackages.removeAt(i); 2351 mSettings.enableSystemPackageLPw(ps.name); 2352 } 2353 } 2354 2355 if (mFirstBoot) { 2356 requestCopyPreoptedFiles(); 2357 } 2358 2359 String customResolverActivity = Resources.getSystem().getString( 2360 R.string.config_customResolverActivity); 2361 if (TextUtils.isEmpty(customResolverActivity)) { 2362 customResolverActivity = null; 2363 } else { 2364 mCustomResolverComponentName = ComponentName.unflattenFromString( 2365 customResolverActivity); 2366 } 2367 2368 long startTime = SystemClock.uptimeMillis(); 2369 2370 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2371 startTime); 2372 2373 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2374 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2375 2376 if (bootClassPath == null) { 2377 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2378 } 2379 2380 if (systemServerClassPath == null) { 2381 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2382 } 2383 2384 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2385 final String[] dexCodeInstructionSets = 2386 getDexCodeInstructionSets( 2387 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2388 2389 /** 2390 * Ensure all external libraries have had dexopt run on them. 2391 */ 2392 if (mSharedLibraries.size() > 0) { 2393 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 2394 // NOTE: For now, we're compiling these system "shared libraries" 2395 // (and framework jars) into all available architectures. It's possible 2396 // to compile them only when we come across an app that uses them (there's 2397 // already logic for that in scanPackageLI) but that adds some complexity. 2398 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2399 final int libCount = mSharedLibraries.size(); 2400 for (int i = 0; i < libCount; i++) { 2401 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 2402 final int versionCount = versionedLib.size(); 2403 for (int j = 0; j < versionCount; j++) { 2404 SharedLibraryEntry libEntry = versionedLib.valueAt(j); 2405 final String libPath = libEntry.path != null 2406 ? libEntry.path : libEntry.apk; 2407 if (libPath == null) { 2408 continue; 2409 } 2410 try { 2411 // Shared libraries do not have profiles so we perform a full 2412 // AOT compilation (if needed). 2413 int dexoptNeeded = DexFile.getDexOptNeeded( 2414 libPath, dexCodeInstructionSet, 2415 getCompilerFilterForReason(REASON_SHARED_APK), 2416 false /* newProfile */); 2417 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2418 mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*", 2419 dexCodeInstructionSet, dexoptNeeded, null, 2420 DEXOPT_PUBLIC, 2421 getCompilerFilterForReason(REASON_SHARED_APK), 2422 StorageManager.UUID_PRIVATE_INTERNAL, 2423 PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK); 2424 } 2425 } catch (FileNotFoundException e) { 2426 Slog.w(TAG, "Library not found: " + libPath); 2427 } catch (IOException | InstallerException e) { 2428 Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? " 2429 + e.getMessage()); 2430 } 2431 } 2432 } 2433 } 2434 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2435 } 2436 2437 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2438 2439 final VersionInfo ver = mSettings.getInternalVersion(); 2440 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2441 2442 // when upgrading from pre-M, promote system app permissions from install to runtime 2443 mPromoteSystemApps = 2444 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2445 2446 // When upgrading from pre-N, we need to handle package extraction like first boot, 2447 // as there is no profiling data available. 2448 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2449 2450 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1; 2451 2452 // save off the names of pre-existing system packages prior to scanning; we don't 2453 // want to automatically grant runtime permissions for new system apps 2454 if (mPromoteSystemApps) { 2455 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2456 while (pkgSettingIter.hasNext()) { 2457 PackageSetting ps = pkgSettingIter.next(); 2458 if (isSystemApp(ps)) { 2459 mExistingSystemPackages.add(ps.name); 2460 } 2461 } 2462 } 2463 2464 mCacheDir = preparePackageParserCache(mIsUpgrade); 2465 2466 // Set flag to monitor and not change apk file paths when 2467 // scanning install directories. 2468 int scanFlags = SCAN_BOOTING | SCAN_INITIAL; 2469 2470 if (mIsUpgrade || mFirstBoot) { 2471 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE; 2472 } 2473 2474 // Collect vendor overlay packages. (Do this before scanning any apps.) 2475 // For security and version matching reason, only consider 2476 // overlay packages if they reside in the right directory. 2477 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags 2478 | PackageParser.PARSE_IS_SYSTEM 2479 | PackageParser.PARSE_IS_SYSTEM_DIR 2480 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2481 2482 // Find base frameworks (resource packages without code). 2483 scanDirTracedLI(frameworkDir, mDefParseFlags 2484 | PackageParser.PARSE_IS_SYSTEM 2485 | PackageParser.PARSE_IS_SYSTEM_DIR 2486 | PackageParser.PARSE_IS_PRIVILEGED, 2487 scanFlags | SCAN_NO_DEX, 0); 2488 2489 // Collected privileged system packages. 2490 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2491 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2492 | PackageParser.PARSE_IS_SYSTEM 2493 | PackageParser.PARSE_IS_SYSTEM_DIR 2494 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2495 2496 // Collect ordinary system packages. 2497 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2498 scanDirTracedLI(systemAppDir, mDefParseFlags 2499 | PackageParser.PARSE_IS_SYSTEM 2500 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2501 2502 // Collect all vendor packages. 2503 File vendorAppDir = new File("/vendor/app"); 2504 try { 2505 vendorAppDir = vendorAppDir.getCanonicalFile(); 2506 } catch (IOException e) { 2507 // failed to look up canonical path, continue with original one 2508 } 2509 scanDirTracedLI(vendorAppDir, mDefParseFlags 2510 | PackageParser.PARSE_IS_SYSTEM 2511 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2512 2513 // Collect all OEM packages. 2514 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2515 scanDirTracedLI(oemAppDir, mDefParseFlags 2516 | PackageParser.PARSE_IS_SYSTEM 2517 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2518 2519 // Prune any system packages that no longer exist. 2520 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2521 if (!mOnlyCore) { 2522 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2523 while (psit.hasNext()) { 2524 PackageSetting ps = psit.next(); 2525 2526 /* 2527 * If this is not a system app, it can't be a 2528 * disable system app. 2529 */ 2530 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2531 continue; 2532 } 2533 2534 /* 2535 * If the package is scanned, it's not erased. 2536 */ 2537 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2538 if (scannedPkg != null) { 2539 /* 2540 * If the system app is both scanned and in the 2541 * disabled packages list, then it must have been 2542 * added via OTA. Remove it from the currently 2543 * scanned package so the previously user-installed 2544 * application can be scanned. 2545 */ 2546 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2547 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2548 + ps.name + "; removing system app. Last known codePath=" 2549 + ps.codePathString + ", installStatus=" + ps.installStatus 2550 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2551 + scannedPkg.mVersionCode); 2552 removePackageLI(scannedPkg, true); 2553 mExpectingBetter.put(ps.name, ps.codePath); 2554 } 2555 2556 continue; 2557 } 2558 2559 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2560 psit.remove(); 2561 logCriticalInfo(Log.WARN, "System package " + ps.name 2562 + " no longer exists; it's data will be wiped"); 2563 // Actual deletion of code and data will be handled by later 2564 // reconciliation step 2565 } else { 2566 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2567 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2568 possiblyDeletedUpdatedSystemApps.add(ps.name); 2569 } 2570 } 2571 } 2572 } 2573 2574 //look for any incomplete package installations 2575 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2576 for (int i = 0; i < deletePkgsList.size(); i++) { 2577 // Actual deletion of code and data will be handled by later 2578 // reconciliation step 2579 final String packageName = deletePkgsList.get(i).name; 2580 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2581 synchronized (mPackages) { 2582 mSettings.removePackageLPw(packageName); 2583 } 2584 } 2585 2586 //delete tmp files 2587 deleteTempPackageFiles(); 2588 2589 // Remove any shared userIDs that have no associated packages 2590 mSettings.pruneSharedUsersLPw(); 2591 2592 if (!mOnlyCore) { 2593 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2594 SystemClock.uptimeMillis()); 2595 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2596 2597 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2598 | PackageParser.PARSE_FORWARD_LOCK, 2599 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2600 2601 /** 2602 * Remove disable package settings for any updated system 2603 * apps that were removed via an OTA. If they're not a 2604 * previously-updated app, remove them completely. 2605 * Otherwise, just revoke their system-level permissions. 2606 */ 2607 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2608 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2609 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2610 2611 String msg; 2612 if (deletedPkg == null) { 2613 msg = "Updated system package " + deletedAppName 2614 + " no longer exists; it's data will be wiped"; 2615 // Actual deletion of code and data will be handled by later 2616 // reconciliation step 2617 } else { 2618 msg = "Updated system app + " + deletedAppName 2619 + " no longer present; removing system privileges for " 2620 + deletedAppName; 2621 2622 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2623 2624 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2625 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2626 } 2627 logCriticalInfo(Log.WARN, msg); 2628 } 2629 2630 /** 2631 * Make sure all system apps that we expected to appear on 2632 * the userdata partition actually showed up. If they never 2633 * appeared, crawl back and revive the system version. 2634 */ 2635 for (int i = 0; i < mExpectingBetter.size(); i++) { 2636 final String packageName = mExpectingBetter.keyAt(i); 2637 if (!mPackages.containsKey(packageName)) { 2638 final File scanFile = mExpectingBetter.valueAt(i); 2639 2640 logCriticalInfo(Log.WARN, "Expected better " + packageName 2641 + " but never showed up; reverting to system"); 2642 2643 int reparseFlags = mDefParseFlags; 2644 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2645 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2646 | PackageParser.PARSE_IS_SYSTEM_DIR 2647 | PackageParser.PARSE_IS_PRIVILEGED; 2648 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2649 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2650 | PackageParser.PARSE_IS_SYSTEM_DIR; 2651 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2652 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2653 | PackageParser.PARSE_IS_SYSTEM_DIR; 2654 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2655 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2656 | PackageParser.PARSE_IS_SYSTEM_DIR; 2657 } else { 2658 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2659 continue; 2660 } 2661 2662 mSettings.enableSystemPackageLPw(packageName); 2663 2664 try { 2665 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2666 } catch (PackageManagerException e) { 2667 Slog.e(TAG, "Failed to parse original system package: " 2668 + e.getMessage()); 2669 } 2670 } 2671 } 2672 } 2673 mExpectingBetter.clear(); 2674 2675 // Resolve the storage manager. 2676 mStorageManagerPackage = getStorageManagerPackageName(); 2677 2678 // Resolve protected action filters. Only the setup wizard is allowed to 2679 // have a high priority filter for these actions. 2680 mSetupWizardPackage = getSetupWizardPackageName(); 2681 if (mProtectedFilters.size() > 0) { 2682 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2683 Slog.i(TAG, "No setup wizard;" 2684 + " All protected intents capped to priority 0"); 2685 } 2686 for (ActivityIntentInfo filter : mProtectedFilters) { 2687 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2688 if (DEBUG_FILTERS) { 2689 Slog.i(TAG, "Found setup wizard;" 2690 + " allow priority " + filter.getPriority() + ";" 2691 + " package: " + filter.activity.info.packageName 2692 + " activity: " + filter.activity.className 2693 + " priority: " + filter.getPriority()); 2694 } 2695 // skip setup wizard; allow it to keep the high priority filter 2696 continue; 2697 } 2698 Slog.w(TAG, "Protected action; cap priority to 0;" 2699 + " package: " + filter.activity.info.packageName 2700 + " activity: " + filter.activity.className 2701 + " origPrio: " + filter.getPriority()); 2702 filter.setPriority(0); 2703 } 2704 } 2705 mDeferProtectedFilters = false; 2706 mProtectedFilters.clear(); 2707 2708 // Now that we know all of the shared libraries, update all clients to have 2709 // the correct library paths. 2710 updateAllSharedLibrariesLPw(null); 2711 2712 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2713 // NOTE: We ignore potential failures here during a system scan (like 2714 // the rest of the commands above) because there's precious little we 2715 // can do about it. A settings error is reported, though. 2716 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/); 2717 } 2718 2719 // Now that we know all the packages we are keeping, 2720 // read and update their last usage times. 2721 mPackageUsage.read(mPackages); 2722 mCompilerStats.read(); 2723 2724 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2725 SystemClock.uptimeMillis()); 2726 Slog.i(TAG, "Time to scan packages: " 2727 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2728 + " seconds"); 2729 2730 // If the platform SDK has changed since the last time we booted, 2731 // we need to re-grant app permission to catch any new ones that 2732 // appear. This is really a hack, and means that apps can in some 2733 // cases get permissions that the user didn't initially explicitly 2734 // allow... it would be nice to have some better way to handle 2735 // this situation. 2736 int updateFlags = UPDATE_PERMISSIONS_ALL; 2737 if (ver.sdkVersion != mSdkVersion) { 2738 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2739 + mSdkVersion + "; regranting permissions for internal storage"); 2740 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2741 } 2742 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2743 ver.sdkVersion = mSdkVersion; 2744 2745 // If this is the first boot or an update from pre-M, and it is a normal 2746 // boot, then we need to initialize the default preferred apps across 2747 // all defined users. 2748 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2749 for (UserInfo user : sUserManager.getUsers(true)) { 2750 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2751 applyFactoryDefaultBrowserLPw(user.id); 2752 primeDomainVerificationsLPw(user.id); 2753 } 2754 } 2755 2756 // Prepare storage for system user really early during boot, 2757 // since core system apps like SettingsProvider and SystemUI 2758 // can't wait for user to start 2759 final int storageFlags; 2760 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2761 storageFlags = StorageManager.FLAG_STORAGE_DE; 2762 } else { 2763 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2764 } 2765 List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, 2766 UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */, 2767 true /* onlyCoreApps */); 2768 mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> { 2769 if (deferPackages == null || deferPackages.isEmpty()) { 2770 return; 2771 } 2772 int count = 0; 2773 for (String pkgName : deferPackages) { 2774 PackageParser.Package pkg = null; 2775 synchronized (mPackages) { 2776 PackageSetting ps = mSettings.getPackageLPr(pkgName); 2777 if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) { 2778 pkg = ps.pkg; 2779 } 2780 } 2781 if (pkg != null) { 2782 synchronized (mInstallLock) { 2783 prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags, 2784 true /* maybeMigrateAppData */); 2785 } 2786 count++; 2787 } 2788 } 2789 Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages"); 2790 }, "prepareAppData"); 2791 2792 // If this is first boot after an OTA, and a normal boot, then 2793 // we need to clear code cache directories. 2794 // Note that we do *not* clear the application profiles. These remain valid 2795 // across OTAs and are used to drive profile verification (post OTA) and 2796 // profile compilation (without waiting to collect a fresh set of profiles). 2797 if (mIsUpgrade && !onlyCore) { 2798 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2799 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2800 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2801 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2802 // No apps are running this early, so no need to freeze 2803 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2804 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2805 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2806 } 2807 } 2808 ver.fingerprint = Build.FINGERPRINT; 2809 } 2810 2811 checkDefaultBrowser(); 2812 2813 // clear only after permissions and other defaults have been updated 2814 mExistingSystemPackages.clear(); 2815 mPromoteSystemApps = false; 2816 2817 // All the changes are done during package scanning. 2818 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2819 2820 // can downgrade to reader 2821 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings"); 2822 mSettings.writeLPr(); 2823 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2824 2825 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2826 // early on (before the package manager declares itself as early) because other 2827 // components in the system server might ask for package contexts for these apps. 2828 // 2829 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2830 // (i.e, that the data partition is unavailable). 2831 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2832 long start = System.nanoTime(); 2833 List<PackageParser.Package> coreApps = new ArrayList<>(); 2834 for (PackageParser.Package pkg : mPackages.values()) { 2835 if (pkg.coreApp) { 2836 coreApps.add(pkg); 2837 } 2838 } 2839 2840 int[] stats = performDexOptUpgrade(coreApps, false, 2841 getCompilerFilterForReason(REASON_CORE_APP)); 2842 2843 final int elapsedTimeSeconds = 2844 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2845 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2846 2847 if (DEBUG_DEXOPT) { 2848 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2849 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2850 } 2851 2852 2853 // TODO: Should we log these stats to tron too ? 2854 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2855 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2856 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2857 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2858 } 2859 2860 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2861 SystemClock.uptimeMillis()); 2862 2863 if (!mOnlyCore) { 2864 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2865 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2866 mRequiredUninstallerPackage = getRequiredUninstallerLPr(); 2867 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2868 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2869 mIntentFilterVerifierComponent); 2870 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2871 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES, 2872 SharedLibraryInfo.VERSION_UNDEFINED); 2873 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2874 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED, 2875 SharedLibraryInfo.VERSION_UNDEFINED); 2876 } else { 2877 mRequiredVerifierPackage = null; 2878 mRequiredInstallerPackage = null; 2879 mRequiredUninstallerPackage = null; 2880 mIntentFilterVerifierComponent = null; 2881 mIntentFilterVerifier = null; 2882 mServicesSystemSharedLibraryPackageName = null; 2883 mSharedSystemSharedLibraryPackageName = null; 2884 } 2885 2886 mInstallerService = new PackageInstallerService(context, this); 2887 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2888 if (ephemeralResolverComponent != null) { 2889 if (DEBUG_EPHEMERAL) { 2890 Slog.d(TAG, "Set ephemeral resolver: " + ephemeralResolverComponent); 2891 } 2892 mInstantAppResolverConnection = 2893 new EphemeralResolverConnection(mContext, ephemeralResolverComponent); 2894 } else { 2895 mInstantAppResolverConnection = null; 2896 } 2897 updateInstantAppInstallerLocked(); 2898 2899 // Read and update the usage of dex files. 2900 // Do this at the end of PM init so that all the packages have their 2901 // data directory reconciled. 2902 // At this point we know the code paths of the packages, so we can validate 2903 // the disk file and build the internal cache. 2904 // The usage file is expected to be small so loading and verifying it 2905 // should take a fairly small time compare to the other activities (e.g. package 2906 // scanning). 2907 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>(); 2908 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 2909 for (int userId : currentUserIds) { 2910 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList()); 2911 } 2912 mDexManager.load(userPackages); 2913 } // synchronized (mPackages) 2914 } // synchronized (mInstallLock) 2915 2916 // Now after opening every single application zip, make sure they 2917 // are all flushed. Not really needed, but keeps things nice and 2918 // tidy. 2919 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC"); 2920 Runtime.getRuntime().gc(); 2921 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2922 2923 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks"); 2924 FallbackCategoryProvider.loadFallbacks(); 2925 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2926 2927 // The initial scanning above does many calls into installd while 2928 // holding the mPackages lock, but we're mostly interested in yelling 2929 // once we have a booted system. 2930 mInstaller.setWarnIfHeld(mPackages); 2931 2932 // Expose private service for system components to use. 2933 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2934 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2935 } 2936 2937 private void updateInstantAppInstallerLocked() { 2938 final ComponentName oldInstantAppInstallerComponent = mInstantAppInstallerComponent; 2939 final ActivityInfo newInstantAppInstaller = getEphemeralInstallerLPr(); 2940 ComponentName newInstantAppInstallerComponent = newInstantAppInstaller == null 2941 ? null : newInstantAppInstaller.getComponentName(); 2942 2943 if (newInstantAppInstallerComponent != null 2944 && !newInstantAppInstallerComponent.equals(oldInstantAppInstallerComponent)) { 2945 if (DEBUG_EPHEMERAL) { 2946 Slog.d(TAG, "Set ephemeral installer: " + newInstantAppInstallerComponent); 2947 } 2948 setUpInstantAppInstallerActivityLP(newInstantAppInstaller); 2949 } else if (DEBUG_EPHEMERAL && newInstantAppInstallerComponent == null) { 2950 Slog.d(TAG, "Unset ephemeral installer; none available"); 2951 } 2952 mInstantAppInstallerComponent = newInstantAppInstallerComponent; 2953 } 2954 2955 private static File preparePackageParserCache(boolean isUpgrade) { 2956 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { 2957 return null; 2958 } 2959 2960 // Disable package parsing on eng builds to allow for faster incremental development. 2961 if ("eng".equals(Build.TYPE)) { 2962 return null; 2963 } 2964 2965 if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) { 2966 Slog.i(TAG, "Disabling package parser cache due to system property."); 2967 return null; 2968 } 2969 2970 // The base directory for the package parser cache lives under /data/system/. 2971 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(), 2972 "package_cache"); 2973 if (cacheBaseDir == null) { 2974 return null; 2975 } 2976 2977 // If this is a system upgrade scenario, delete the contents of the package cache dir. 2978 // This also serves to "GC" unused entries when the package cache version changes (which 2979 // can only happen during upgrades). 2980 if (isUpgrade) { 2981 FileUtils.deleteContents(cacheBaseDir); 2982 } 2983 2984 2985 // Return the versioned package cache directory. This is something like 2986 // "/data/system/package_cache/1" 2987 File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); 2988 2989 // The following is a workaround to aid development on non-numbered userdebug 2990 // builds or cases where "adb sync" is used on userdebug builds. If we detect that 2991 // the system partition is newer. 2992 // 2993 // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build 2994 // that starts with "eng." to signify that this is an engineering build and not 2995 // destined for release. 2996 if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) { 2997 Slog.w(TAG, "Wiping cache directory because the system partition changed."); 2998 2999 // Heuristic: If the /system directory has been modified recently due to an "adb sync" 3000 // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable 3001 // in general and should not be used for production changes. In this specific case, 3002 // we know that they will work. 3003 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 3004 if (cacheDir.lastModified() < frameworkDir.lastModified()) { 3005 FileUtils.deleteContents(cacheBaseDir); 3006 cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); 3007 } 3008 } 3009 3010 return cacheDir; 3011 } 3012 3013 @Override 3014 public boolean isFirstBoot() { 3015 return mFirstBoot; 3016 } 3017 3018 @Override 3019 public boolean isOnlyCoreApps() { 3020 return mOnlyCore; 3021 } 3022 3023 @Override 3024 public boolean isUpgrade() { 3025 return mIsUpgrade; 3026 } 3027 3028 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 3029 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 3030 3031 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 3032 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3033 UserHandle.USER_SYSTEM); 3034 if (matches.size() == 1) { 3035 return matches.get(0).getComponentInfo().packageName; 3036 } else if (matches.size() == 0) { 3037 Log.e(TAG, "There should probably be a verifier, but, none were found"); 3038 return null; 3039 } 3040 throw new RuntimeException("There must be exactly one verifier; found " + matches); 3041 } 3042 3043 private @NonNull String getRequiredSharedLibraryLPr(String name, int version) { 3044 synchronized (mPackages) { 3045 SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version); 3046 if (libraryEntry == null) { 3047 throw new IllegalStateException("Missing required shared library:" + name); 3048 } 3049 return libraryEntry.apk; 3050 } 3051 } 3052 3053 private @NonNull String getRequiredInstallerLPr() { 3054 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 3055 intent.addCategory(Intent.CATEGORY_DEFAULT); 3056 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 3057 3058 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 3059 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3060 UserHandle.USER_SYSTEM); 3061 if (matches.size() == 1) { 3062 ResolveInfo resolveInfo = matches.get(0); 3063 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 3064 throw new RuntimeException("The installer must be a privileged app"); 3065 } 3066 return matches.get(0).getComponentInfo().packageName; 3067 } else { 3068 throw new RuntimeException("There must be exactly one installer; found " + matches); 3069 } 3070 } 3071 3072 private @NonNull String getRequiredUninstallerLPr() { 3073 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 3074 intent.addCategory(Intent.CATEGORY_DEFAULT); 3075 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null)); 3076 3077 final ResolveInfo resolveInfo = resolveIntent(intent, null, 3078 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3079 UserHandle.USER_SYSTEM); 3080 if (resolveInfo == null || 3081 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) { 3082 throw new RuntimeException("There must be exactly one uninstaller; found " 3083 + resolveInfo); 3084 } 3085 return resolveInfo.getComponentInfo().packageName; 3086 } 3087 3088 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 3089 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 3090 3091 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 3092 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 3093 UserHandle.USER_SYSTEM); 3094 ResolveInfo best = null; 3095 final int N = matches.size(); 3096 for (int i = 0; i < N; i++) { 3097 final ResolveInfo cur = matches.get(i); 3098 final String packageName = cur.getComponentInfo().packageName; 3099 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 3100 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 3101 continue; 3102 } 3103 3104 if (best == null || cur.priority > best.priority) { 3105 best = cur; 3106 } 3107 } 3108 3109 if (best != null) { 3110 return best.getComponentInfo().getComponentName(); 3111 } else { 3112 throw new RuntimeException("There must be at least one intent filter verifier"); 3113 } 3114 } 3115 3116 private @Nullable ComponentName getEphemeralResolverLPr() { 3117 final String[] packageArray = 3118 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 3119 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 3120 if (DEBUG_EPHEMERAL) { 3121 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 3122 } 3123 return null; 3124 } 3125 3126 final int resolveFlags = 3127 MATCH_DIRECT_BOOT_AWARE 3128 | MATCH_DIRECT_BOOT_UNAWARE 3129 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 3130 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 3131 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 3132 resolveFlags, UserHandle.USER_SYSTEM); 3133 3134 final int N = resolvers.size(); 3135 if (N == 0) { 3136 if (DEBUG_EPHEMERAL) { 3137 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 3138 } 3139 return null; 3140 } 3141 3142 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 3143 for (int i = 0; i < N; i++) { 3144 final ResolveInfo info = resolvers.get(i); 3145 3146 if (info.serviceInfo == null) { 3147 continue; 3148 } 3149 3150 final String packageName = info.serviceInfo.packageName; 3151 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 3152 if (DEBUG_EPHEMERAL) { 3153 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 3154 + " pkg: " + packageName + ", info:" + info); 3155 } 3156 continue; 3157 } 3158 3159 if (DEBUG_EPHEMERAL) { 3160 Slog.v(TAG, "Ephemeral resolver found;" 3161 + " pkg: " + packageName + ", info:" + info); 3162 } 3163 return new ComponentName(packageName, info.serviceInfo.name); 3164 } 3165 if (DEBUG_EPHEMERAL) { 3166 Slog.v(TAG, "Ephemeral resolver NOT found"); 3167 } 3168 return null; 3169 } 3170 3171 private @Nullable ActivityInfo getEphemeralInstallerLPr() { 3172 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 3173 intent.addCategory(Intent.CATEGORY_DEFAULT); 3174 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 3175 3176 final int resolveFlags = 3177 MATCH_DIRECT_BOOT_AWARE 3178 | MATCH_DIRECT_BOOT_UNAWARE 3179 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 3180 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 3181 resolveFlags, UserHandle.USER_SYSTEM); 3182 Iterator<ResolveInfo> iter = matches.iterator(); 3183 while (iter.hasNext()) { 3184 final ResolveInfo rInfo = iter.next(); 3185 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); 3186 if (ps != null) { 3187 final PermissionsState permissionsState = ps.getPermissionsState(); 3188 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) { 3189 continue; 3190 } 3191 } 3192 iter.remove(); 3193 } 3194 if (matches.size() == 0) { 3195 return null; 3196 } else if (matches.size() == 1) { 3197 return (ActivityInfo) matches.get(0).getComponentInfo(); 3198 } else { 3199 throw new RuntimeException( 3200 "There must be at most one ephemeral installer; found " + matches); 3201 } 3202 } 3203 3204 private void primeDomainVerificationsLPw(int userId) { 3205 if (DEBUG_DOMAIN_VERIFICATION) { 3206 Slog.d(TAG, "Priming domain verifications in user " + userId); 3207 } 3208 3209 SystemConfig systemConfig = SystemConfig.getInstance(); 3210 ArraySet<String> packages = systemConfig.getLinkedApps(); 3211 3212 for (String packageName : packages) { 3213 PackageParser.Package pkg = mPackages.get(packageName); 3214 if (pkg != null) { 3215 if (!pkg.isSystemApp()) { 3216 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 3217 continue; 3218 } 3219 3220 ArraySet<String> domains = null; 3221 for (PackageParser.Activity a : pkg.activities) { 3222 for (ActivityIntentInfo filter : a.intents) { 3223 if (hasValidDomains(filter)) { 3224 if (domains == null) { 3225 domains = new ArraySet<String>(); 3226 } 3227 domains.addAll(filter.getHostsList()); 3228 } 3229 } 3230 } 3231 3232 if (domains != null && domains.size() > 0) { 3233 if (DEBUG_DOMAIN_VERIFICATION) { 3234 Slog.v(TAG, " + " + packageName); 3235 } 3236 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 3237 // state w.r.t. the formal app-linkage "no verification attempted" state; 3238 // and then 'always' in the per-user state actually used for intent resolution. 3239 final IntentFilterVerificationInfo ivi; 3240 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains); 3241 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 3242 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 3243 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 3244 } else { 3245 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 3246 + "' does not handle web links"); 3247 } 3248 } else { 3249 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 3250 } 3251 } 3252 3253 scheduleWritePackageRestrictionsLocked(userId); 3254 scheduleWriteSettingsLocked(); 3255 } 3256 3257 private void applyFactoryDefaultBrowserLPw(int userId) { 3258 // The default browser app's package name is stored in a string resource, 3259 // with a product-specific overlay used for vendor customization. 3260 String browserPkg = mContext.getResources().getString( 3261 com.android.internal.R.string.default_browser); 3262 if (!TextUtils.isEmpty(browserPkg)) { 3263 // non-empty string => required to be a known package 3264 PackageSetting ps = mSettings.mPackages.get(browserPkg); 3265 if (ps == null) { 3266 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 3267 browserPkg = null; 3268 } else { 3269 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3270 } 3271 } 3272 3273 // Nothing valid explicitly set? Make the factory-installed browser the explicit 3274 // default. If there's more than one, just leave everything alone. 3275 if (browserPkg == null) { 3276 calculateDefaultBrowserLPw(userId); 3277 } 3278 } 3279 3280 private void calculateDefaultBrowserLPw(int userId) { 3281 List<String> allBrowsers = resolveAllBrowserApps(userId); 3282 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 3283 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3284 } 3285 3286 private List<String> resolveAllBrowserApps(int userId) { 3287 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 3288 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3289 PackageManager.MATCH_ALL, userId); 3290 3291 final int count = list.size(); 3292 List<String> result = new ArrayList<String>(count); 3293 for (int i=0; i<count; i++) { 3294 ResolveInfo info = list.get(i); 3295 if (info.activityInfo == null 3296 || !info.handleAllWebDataURI 3297 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 3298 || result.contains(info.activityInfo.packageName)) { 3299 continue; 3300 } 3301 result.add(info.activityInfo.packageName); 3302 } 3303 3304 return result; 3305 } 3306 3307 private boolean packageIsBrowser(String packageName, int userId) { 3308 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3309 PackageManager.MATCH_ALL, userId); 3310 final int N = list.size(); 3311 for (int i = 0; i < N; i++) { 3312 ResolveInfo info = list.get(i); 3313 if (packageName.equals(info.activityInfo.packageName)) { 3314 return true; 3315 } 3316 } 3317 return false; 3318 } 3319 3320 private void checkDefaultBrowser() { 3321 final int myUserId = UserHandle.myUserId(); 3322 final String packageName = getDefaultBrowserPackageName(myUserId); 3323 if (packageName != null) { 3324 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 3325 if (info == null) { 3326 Slog.w(TAG, "Default browser no longer installed: " + packageName); 3327 synchronized (mPackages) { 3328 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 3329 } 3330 } 3331 } 3332 } 3333 3334 @Override 3335 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 3336 throws RemoteException { 3337 try { 3338 return super.onTransact(code, data, reply, flags); 3339 } catch (RuntimeException e) { 3340 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 3341 Slog.wtf(TAG, "Package Manager Crash", e); 3342 } 3343 throw e; 3344 } 3345 } 3346 3347 static int[] appendInts(int[] cur, int[] add) { 3348 if (add == null) return cur; 3349 if (cur == null) return add; 3350 final int N = add.length; 3351 for (int i=0; i<N; i++) { 3352 cur = appendInt(cur, add[i]); 3353 } 3354 return cur; 3355 } 3356 3357 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3358 if (!sUserManager.exists(userId)) return null; 3359 if (ps == null) { 3360 return null; 3361 } 3362 final PackageParser.Package p = ps.pkg; 3363 if (p == null) { 3364 return null; 3365 } 3366 // Filter out ephemeral app metadata: 3367 // * The system/shell/root can see metadata for any app 3368 // * An installed app can see metadata for 1) other installed apps 3369 // and 2) ephemeral apps that have explicitly interacted with it 3370 // * Ephemeral apps can only see their own data and exposed installed apps 3371 // * Holding a signature permission allows seeing instant apps 3372 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); 3373 if (callingAppId != Process.SYSTEM_UID 3374 && callingAppId != Process.SHELL_UID 3375 && callingAppId != Process.ROOT_UID 3376 && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS, 3377 Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) { 3378 final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid()); 3379 if (instantAppPackageName != null) { 3380 // ephemeral apps can only get information on themselves or 3381 // installed apps that are exposed. 3382 if (!instantAppPackageName.equals(p.packageName) 3383 && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) { 3384 return null; 3385 } 3386 } else { 3387 if (ps.getInstantApp(userId)) { 3388 // only get access to the ephemeral app if we've been granted access 3389 if (!mInstantAppRegistry.isInstantAccessGranted( 3390 userId, callingAppId, ps.appId)) { 3391 return null; 3392 } 3393 } 3394 } 3395 } 3396 3397 final PermissionsState permissionsState = ps.getPermissionsState(); 3398 3399 // Compute GIDs only if requested 3400 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3401 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3402 // Compute granted permissions only if package has requested permissions 3403 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3404 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3405 final PackageUserState state = ps.readUserState(userId); 3406 3407 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 3408 && ps.isSystem()) { 3409 flags |= MATCH_ANY_USER; 3410 } 3411 3412 PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags, 3413 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3414 3415 if (packageInfo == null) { 3416 return null; 3417 } 3418 3419 rebaseEnabledOverlays(packageInfo.applicationInfo, userId); 3420 3421 packageInfo.packageName = packageInfo.applicationInfo.packageName = 3422 resolveExternalPackageNameLPr(p); 3423 3424 return packageInfo; 3425 } 3426 3427 @Override 3428 public void checkPackageStartable(String packageName, int userId) { 3429 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3430 3431 synchronized (mPackages) { 3432 final PackageSetting ps = mSettings.mPackages.get(packageName); 3433 if (ps == null) { 3434 throw new SecurityException("Package " + packageName + " was not found!"); 3435 } 3436 3437 if (!ps.getInstalled(userId)) { 3438 throw new SecurityException( 3439 "Package " + packageName + " was not installed for user " + userId + "!"); 3440 } 3441 3442 if (mSafeMode && !ps.isSystem()) { 3443 throw new SecurityException("Package " + packageName + " not a system app!"); 3444 } 3445 3446 if (mFrozenPackages.contains(packageName)) { 3447 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3448 } 3449 3450 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3451 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3452 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3453 } 3454 } 3455 } 3456 3457 @Override 3458 public boolean isPackageAvailable(String packageName, int userId) { 3459 if (!sUserManager.exists(userId)) return false; 3460 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3461 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3462 synchronized (mPackages) { 3463 PackageParser.Package p = mPackages.get(packageName); 3464 if (p != null) { 3465 final PackageSetting ps = (PackageSetting) p.mExtras; 3466 if (ps != null) { 3467 final PackageUserState state = ps.readUserState(userId); 3468 if (state != null) { 3469 return PackageParser.isAvailable(state); 3470 } 3471 } 3472 } 3473 } 3474 return false; 3475 } 3476 3477 @Override 3478 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3479 return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST, 3480 flags, userId); 3481 } 3482 3483 @Override 3484 public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage, 3485 int flags, int userId) { 3486 return getPackageInfoInternal(versionedPackage.getPackageName(), 3487 // TODO: We will change version code to long, so in the new API it is long 3488 (int) versionedPackage.getVersionCode(), flags, userId); 3489 } 3490 3491 private PackageInfo getPackageInfoInternal(String packageName, int versionCode, 3492 int flags, int userId) { 3493 if (!sUserManager.exists(userId)) return null; 3494 flags = updateFlagsForPackage(flags, userId, packageName); 3495 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3496 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3497 3498 // reader 3499 synchronized (mPackages) { 3500 // Normalize package name to handle renamed packages and static libs 3501 packageName = resolveInternalPackageNameLPr(packageName, versionCode); 3502 3503 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3504 if (matchFactoryOnly) { 3505 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3506 if (ps != null) { 3507 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3508 return null; 3509 } 3510 return generatePackageInfo(ps, flags, userId); 3511 } 3512 } 3513 3514 PackageParser.Package p = mPackages.get(packageName); 3515 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3516 return null; 3517 } 3518 if (DEBUG_PACKAGE_INFO) 3519 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3520 if (p != null) { 3521 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras, 3522 Binder.getCallingUid(), userId)) { 3523 return null; 3524 } 3525 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3526 } 3527 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) { 3528 final PackageSetting ps = mSettings.mPackages.get(packageName); 3529 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3530 return null; 3531 } 3532 return generatePackageInfo(ps, flags, userId); 3533 } 3534 } 3535 return null; 3536 } 3537 3538 3539 private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) { 3540 // System/shell/root get to see all static libs 3541 final int appId = UserHandle.getAppId(uid); 3542 if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID 3543 || appId == Process.ROOT_UID) { 3544 return false; 3545 } 3546 3547 // No package means no static lib as it is always on internal storage 3548 if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) { 3549 return false; 3550 } 3551 3552 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName, 3553 ps.pkg.staticSharedLibVersion); 3554 if (libEntry == null) { 3555 return false; 3556 } 3557 3558 final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); 3559 final String[] uidPackageNames = getPackagesForUid(resolvedUid); 3560 if (uidPackageNames == null) { 3561 return true; 3562 } 3563 3564 for (String uidPackageName : uidPackageNames) { 3565 if (ps.name.equals(uidPackageName)) { 3566 return false; 3567 } 3568 PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName); 3569 if (uidPs != null) { 3570 final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries, 3571 libEntry.info.getName()); 3572 if (index < 0) { 3573 continue; 3574 } 3575 if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) { 3576 return false; 3577 } 3578 } 3579 } 3580 return true; 3581 } 3582 3583 @Override 3584 public String[] currentToCanonicalPackageNames(String[] names) { 3585 String[] out = new String[names.length]; 3586 // reader 3587 synchronized (mPackages) { 3588 for (int i=names.length-1; i>=0; i--) { 3589 PackageSetting ps = mSettings.mPackages.get(names[i]); 3590 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3591 } 3592 } 3593 return out; 3594 } 3595 3596 @Override 3597 public String[] canonicalToCurrentPackageNames(String[] names) { 3598 String[] out = new String[names.length]; 3599 // reader 3600 synchronized (mPackages) { 3601 for (int i=names.length-1; i>=0; i--) { 3602 String cur = mSettings.getRenamedPackageLPr(names[i]); 3603 out[i] = cur != null ? cur : names[i]; 3604 } 3605 } 3606 return out; 3607 } 3608 3609 @Override 3610 public int getPackageUid(String packageName, int flags, int userId) { 3611 if (!sUserManager.exists(userId)) return -1; 3612 flags = updateFlagsForPackage(flags, userId, packageName); 3613 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3614 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3615 3616 // reader 3617 synchronized (mPackages) { 3618 final PackageParser.Package p = mPackages.get(packageName); 3619 if (p != null && p.isMatch(flags)) { 3620 return UserHandle.getUid(userId, p.applicationInfo.uid); 3621 } 3622 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3623 final PackageSetting ps = mSettings.mPackages.get(packageName); 3624 if (ps != null && ps.isMatch(flags)) { 3625 return UserHandle.getUid(userId, ps.appId); 3626 } 3627 } 3628 } 3629 3630 return -1; 3631 } 3632 3633 @Override 3634 public int[] getPackageGids(String packageName, int flags, int userId) { 3635 if (!sUserManager.exists(userId)) return null; 3636 flags = updateFlagsForPackage(flags, userId, packageName); 3637 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3638 false /* requireFullPermission */, false /* checkShell */, 3639 "getPackageGids"); 3640 3641 // reader 3642 synchronized (mPackages) { 3643 final PackageParser.Package p = mPackages.get(packageName); 3644 if (p != null && p.isMatch(flags)) { 3645 PackageSetting ps = (PackageSetting) p.mExtras; 3646 // TODO: Shouldn't this be checking for package installed state for userId and 3647 // return null? 3648 return ps.getPermissionsState().computeGids(userId); 3649 } 3650 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3651 final PackageSetting ps = mSettings.mPackages.get(packageName); 3652 if (ps != null && ps.isMatch(flags)) { 3653 return ps.getPermissionsState().computeGids(userId); 3654 } 3655 } 3656 } 3657 3658 return null; 3659 } 3660 3661 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3662 if (bp.perm != null) { 3663 return PackageParser.generatePermissionInfo(bp.perm, flags); 3664 } 3665 PermissionInfo pi = new PermissionInfo(); 3666 pi.name = bp.name; 3667 pi.packageName = bp.sourcePackage; 3668 pi.nonLocalizedLabel = bp.name; 3669 pi.protectionLevel = bp.protectionLevel; 3670 return pi; 3671 } 3672 3673 @Override 3674 public PermissionInfo getPermissionInfo(String name, int flags) { 3675 // reader 3676 synchronized (mPackages) { 3677 final BasePermission p = mSettings.mPermissions.get(name); 3678 if (p != null) { 3679 return generatePermissionInfo(p, flags); 3680 } 3681 return null; 3682 } 3683 } 3684 3685 @Override 3686 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3687 int flags) { 3688 // reader 3689 synchronized (mPackages) { 3690 if (group != null && !mPermissionGroups.containsKey(group)) { 3691 // This is thrown as NameNotFoundException 3692 return null; 3693 } 3694 3695 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3696 for (BasePermission p : mSettings.mPermissions.values()) { 3697 if (group == null) { 3698 if (p.perm == null || p.perm.info.group == null) { 3699 out.add(generatePermissionInfo(p, flags)); 3700 } 3701 } else { 3702 if (p.perm != null && group.equals(p.perm.info.group)) { 3703 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3704 } 3705 } 3706 } 3707 return new ParceledListSlice<>(out); 3708 } 3709 } 3710 3711 @Override 3712 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3713 // reader 3714 synchronized (mPackages) { 3715 return PackageParser.generatePermissionGroupInfo( 3716 mPermissionGroups.get(name), flags); 3717 } 3718 } 3719 3720 @Override 3721 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3722 // reader 3723 synchronized (mPackages) { 3724 final int N = mPermissionGroups.size(); 3725 ArrayList<PermissionGroupInfo> out 3726 = new ArrayList<PermissionGroupInfo>(N); 3727 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3728 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3729 } 3730 return new ParceledListSlice<>(out); 3731 } 3732 } 3733 3734 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3735 int uid, int userId) { 3736 if (!sUserManager.exists(userId)) return null; 3737 PackageSetting ps = mSettings.mPackages.get(packageName); 3738 if (ps != null) { 3739 if (filterSharedLibPackageLPr(ps, uid, userId)) { 3740 return null; 3741 } 3742 if (ps.pkg == null) { 3743 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3744 if (pInfo != null) { 3745 return pInfo.applicationInfo; 3746 } 3747 return null; 3748 } 3749 ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 3750 ps.readUserState(userId), userId); 3751 if (ai != null) { 3752 rebaseEnabledOverlays(ai, userId); 3753 ai.packageName = resolveExternalPackageNameLPr(ps.pkg); 3754 } 3755 return ai; 3756 } 3757 return null; 3758 } 3759 3760 @Override 3761 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3762 if (!sUserManager.exists(userId)) return null; 3763 flags = updateFlagsForApplication(flags, userId, packageName); 3764 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3765 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3766 3767 // writer 3768 synchronized (mPackages) { 3769 // Normalize package name to handle renamed packages and static libs 3770 packageName = resolveInternalPackageNameLPr(packageName, 3771 PackageManager.VERSION_CODE_HIGHEST); 3772 3773 PackageParser.Package p = mPackages.get(packageName); 3774 if (DEBUG_PACKAGE_INFO) Log.v( 3775 TAG, "getApplicationInfo " + packageName 3776 + ": " + p); 3777 if (p != null) { 3778 PackageSetting ps = mSettings.mPackages.get(packageName); 3779 if (ps == null) return null; 3780 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 3781 return null; 3782 } 3783 // Note: isEnabledLP() does not apply here - always return info 3784 ApplicationInfo ai = PackageParser.generateApplicationInfo( 3785 p, flags, ps.readUserState(userId), userId); 3786 if (ai != null) { 3787 rebaseEnabledOverlays(ai, userId); 3788 ai.packageName = resolveExternalPackageNameLPr(p); 3789 } 3790 return ai; 3791 } 3792 if ("android".equals(packageName)||"system".equals(packageName)) { 3793 return mAndroidApplication; 3794 } 3795 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3796 // Already generates the external package name 3797 return generateApplicationInfoFromSettingsLPw(packageName, 3798 Binder.getCallingUid(), flags, userId); 3799 } 3800 } 3801 return null; 3802 } 3803 3804 private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) { 3805 List<String> paths = new ArrayList<>(); 3806 ArrayMap<String, ArrayList<String>> userSpecificOverlays = 3807 mEnabledOverlayPaths.get(userId); 3808 if (userSpecificOverlays != null) { 3809 if (!"android".equals(ai.packageName)) { 3810 ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android"); 3811 if (frameworkOverlays != null) { 3812 paths.addAll(frameworkOverlays); 3813 } 3814 } 3815 3816 ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName); 3817 if (appOverlays != null) { 3818 paths.addAll(appOverlays); 3819 } 3820 } 3821 ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null; 3822 } 3823 3824 private String normalizePackageNameLPr(String packageName) { 3825 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName); 3826 return normalizedPackageName != null ? normalizedPackageName : packageName; 3827 } 3828 3829 @Override 3830 public void deletePreloadsFileCache() { 3831 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) { 3832 throw new SecurityException("Only system or settings may call deletePreloadsFileCache"); 3833 } 3834 File dir = Environment.getDataPreloadsFileCacheDirectory(); 3835 Slog.i(TAG, "Deleting preloaded file cache " + dir); 3836 FileUtils.deleteContents(dir); 3837 } 3838 3839 @Override 3840 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3841 final IPackageDataObserver observer) { 3842 mContext.enforceCallingOrSelfPermission( 3843 android.Manifest.permission.CLEAR_APP_CACHE, null); 3844 mHandler.post(() -> { 3845 boolean success = false; 3846 try { 3847 freeStorage(volumeUuid, freeStorageSize, 0); 3848 success = true; 3849 } catch (IOException e) { 3850 Slog.w(TAG, e); 3851 } 3852 if (observer != null) { 3853 try { 3854 observer.onRemoveCompleted(null, success); 3855 } catch (RemoteException e) { 3856 Slog.w(TAG, e); 3857 } 3858 } 3859 }); 3860 } 3861 3862 @Override 3863 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3864 final IntentSender pi) { 3865 mContext.enforceCallingOrSelfPermission( 3866 android.Manifest.permission.CLEAR_APP_CACHE, TAG); 3867 mHandler.post(() -> { 3868 boolean success = false; 3869 try { 3870 freeStorage(volumeUuid, freeStorageSize, 0); 3871 success = true; 3872 } catch (IOException e) { 3873 Slog.w(TAG, e); 3874 } 3875 if (pi != null) { 3876 try { 3877 pi.sendIntent(null, success ? 1 : 0, null, null, null); 3878 } catch (SendIntentException e) { 3879 Slog.w(TAG, e); 3880 } 3881 } 3882 }); 3883 } 3884 3885 /** 3886 * Blocking call to clear various types of cached data across the system 3887 * until the requested bytes are available. 3888 */ 3889 public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException { 3890 final StorageManager storage = mContext.getSystemService(StorageManager.class); 3891 final File file = storage.findPathForUuid(volumeUuid); 3892 if (file.getUsableSpace() >= bytes) return; 3893 3894 if (ENABLE_FREE_CACHE_V2) { 3895 final boolean aggressive = (storageFlags 3896 & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0; 3897 final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, 3898 volumeUuid); 3899 3900 // 1. Pre-flight to determine if we have any chance to succeed 3901 // 2. Consider preloaded data (after 1w honeymoon, unless aggressive) 3902 if (internalVolume && (aggressive || SystemProperties 3903 .getBoolean("persist.sys.preloads.file_cache_expired", false))) { 3904 deletePreloadsFileCache(); 3905 if (file.getUsableSpace() >= bytes) return; 3906 } 3907 3908 // 3. Consider parsed APK data (aggressive only) 3909 if (internalVolume && aggressive) { 3910 FileUtils.deleteContents(mCacheDir); 3911 if (file.getUsableSpace() >= bytes) return; 3912 } 3913 3914 // 4. Consider cached app data (above quotas) 3915 try { 3916 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2); 3917 } catch (InstallerException ignored) { 3918 } 3919 if (file.getUsableSpace() >= bytes) return; 3920 3921 // 5. Consider shared libraries with refcount=0 and age>2h 3922 // 6. Consider dexopt output (aggressive only) 3923 // 7. Consider ephemeral apps not used in last week 3924 3925 // 8. Consider cached app data (below quotas) 3926 try { 3927 mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2 3928 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA); 3929 } catch (InstallerException ignored) { 3930 } 3931 if (file.getUsableSpace() >= bytes) return; 3932 3933 // 9. Consider DropBox entries 3934 // 10. Consider ephemeral cookies 3935 3936 } else { 3937 try { 3938 mInstaller.freeCache(volumeUuid, bytes, 0); 3939 } catch (InstallerException ignored) { 3940 } 3941 if (file.getUsableSpace() >= bytes) return; 3942 } 3943 3944 throw new IOException("Failed to free " + bytes + " on storage device at " + file); 3945 } 3946 3947 /** 3948 * Update given flags based on encryption status of current user. 3949 */ 3950 private int updateFlags(int flags, int userId) { 3951 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3952 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3953 // Caller expressed an explicit opinion about what encryption 3954 // aware/unaware components they want to see, so fall through and 3955 // give them what they want 3956 } else { 3957 // Caller expressed no opinion, so match based on user state 3958 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3959 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3960 } else { 3961 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3962 } 3963 } 3964 return flags; 3965 } 3966 3967 private UserManagerInternal getUserManagerInternal() { 3968 if (mUserManagerInternal == null) { 3969 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3970 } 3971 return mUserManagerInternal; 3972 } 3973 3974 private DeviceIdleController.LocalService getDeviceIdleController() { 3975 if (mDeviceIdleController == null) { 3976 mDeviceIdleController = 3977 LocalServices.getService(DeviceIdleController.LocalService.class); 3978 } 3979 return mDeviceIdleController; 3980 } 3981 3982 /** 3983 * Update given flags when being used to request {@link PackageInfo}. 3984 */ 3985 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3986 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM; 3987 boolean triaged = true; 3988 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3989 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3990 // Caller is asking for component details, so they'd better be 3991 // asking for specific encryption matching behavior, or be triaged 3992 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3993 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3994 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3995 triaged = false; 3996 } 3997 } 3998 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3999 | PackageManager.MATCH_SYSTEM_ONLY 4000 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 4001 triaged = false; 4002 } 4003 if ((flags & PackageManager.MATCH_ANY_USER) != 0) { 4004 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 4005 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at " 4006 + Debug.getCallers(5)); 4007 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser 4008 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) { 4009 // If the caller wants all packages and has a restricted profile associated with it, 4010 // then match all users. This is to make sure that launchers that need to access work 4011 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using 4012 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380 4013 flags |= PackageManager.MATCH_ANY_USER; 4014 } 4015 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 4016 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 4017 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 4018 } 4019 return updateFlags(flags, userId); 4020 } 4021 4022 /** 4023 * Update given flags when being used to request {@link ApplicationInfo}. 4024 */ 4025 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 4026 return updateFlagsForPackage(flags, userId, cookie); 4027 } 4028 4029 /** 4030 * Update given flags when being used to request {@link ComponentInfo}. 4031 */ 4032 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 4033 if (cookie instanceof Intent) { 4034 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 4035 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 4036 } 4037 } 4038 4039 boolean triaged = true; 4040 // Caller is asking for component details, so they'd better be 4041 // asking for specific encryption matching behavior, or be triaged 4042 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 4043 | PackageManager.MATCH_DIRECT_BOOT_AWARE 4044 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 4045 triaged = false; 4046 } 4047 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 4048 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 4049 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 4050 } 4051 4052 return updateFlags(flags, userId); 4053 } 4054 4055 /** 4056 * Update given intent when being used to request {@link ResolveInfo}. 4057 */ 4058 private Intent updateIntentForResolve(Intent intent) { 4059 if (intent.getSelector() != null) { 4060 intent = intent.getSelector(); 4061 } 4062 if (DEBUG_PREFERRED) { 4063 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4064 } 4065 return intent; 4066 } 4067 4068 /** 4069 * Update given flags when being used to request {@link ResolveInfo}. 4070 * <p>Instant apps are resolved specially, depending upon context. Minimally, 4071 * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT} 4072 * flag set. However, this flag is only honoured in three circumstances: 4073 * <ul> 4074 * <li>when called from a system process</li> 4075 * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li> 4076 * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW} 4077 * action and a {@code android.intent.category.BROWSABLE} category</li> 4078 * </ul> 4079 */ 4080 int updateFlagsForResolve(int flags, int userId, Intent intent, boolean includeInstantApp) { 4081 // Safe mode means we shouldn't match any third-party components 4082 if (mSafeMode) { 4083 flags |= PackageManager.MATCH_SYSTEM_ONLY; 4084 } 4085 final int callingUid = Binder.getCallingUid(); 4086 if (getInstantAppPackageName(callingUid) != null) { 4087 // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components 4088 flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; 4089 flags |= PackageManager.MATCH_INSTANT; 4090 } else { 4091 // Otherwise, prevent leaking ephemeral components 4092 final boolean isSpecialProcess = 4093 callingUid == Process.SYSTEM_UID 4094 || callingUid == Process.SHELL_UID 4095 || callingUid == 0; 4096 final boolean allowMatchInstant = 4097 (includeInstantApp 4098 && Intent.ACTION_VIEW.equals(intent.getAction()) 4099 && intent.hasCategory(Intent.CATEGORY_BROWSABLE) 4100 && hasWebURI(intent)) 4101 || isSpecialProcess 4102 || mContext.checkCallingOrSelfPermission( 4103 android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED; 4104 flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; 4105 if (!allowMatchInstant) { 4106 flags &= ~PackageManager.MATCH_INSTANT; 4107 } 4108 } 4109 return updateFlagsForComponent(flags, userId, intent /*cookie*/); 4110 } 4111 4112 @Override 4113 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 4114 if (!sUserManager.exists(userId)) return null; 4115 flags = updateFlagsForComponent(flags, userId, component); 4116 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4117 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 4118 synchronized (mPackages) { 4119 PackageParser.Activity a = mActivities.mActivities.get(component); 4120 4121 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 4122 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 4123 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4124 if (ps == null) return null; 4125 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 4126 userId); 4127 } 4128 if (mResolveComponentName.equals(component)) { 4129 return PackageParser.generateActivityInfo(mResolveActivity, flags, 4130 new PackageUserState(), userId); 4131 } 4132 } 4133 return null; 4134 } 4135 4136 @Override 4137 public boolean activitySupportsIntent(ComponentName component, Intent intent, 4138 String resolvedType) { 4139 synchronized (mPackages) { 4140 if (component.equals(mResolveComponentName)) { 4141 // The resolver supports EVERYTHING! 4142 return true; 4143 } 4144 PackageParser.Activity a = mActivities.mActivities.get(component); 4145 if (a == null) { 4146 return false; 4147 } 4148 for (int i=0; i<a.intents.size(); i++) { 4149 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 4150 intent.getData(), intent.getCategories(), TAG) >= 0) { 4151 return true; 4152 } 4153 } 4154 return false; 4155 } 4156 } 4157 4158 @Override 4159 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 4160 if (!sUserManager.exists(userId)) return null; 4161 flags = updateFlagsForComponent(flags, userId, component); 4162 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4163 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 4164 synchronized (mPackages) { 4165 PackageParser.Activity a = mReceivers.mActivities.get(component); 4166 if (DEBUG_PACKAGE_INFO) Log.v( 4167 TAG, "getReceiverInfo " + component + ": " + a); 4168 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 4169 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4170 if (ps == null) return null; 4171 ActivityInfo ri = PackageParser.generateActivityInfo(a, flags, 4172 ps.readUserState(userId), userId); 4173 if (ri != null) { 4174 rebaseEnabledOverlays(ri.applicationInfo, userId); 4175 } 4176 return ri; 4177 } 4178 } 4179 return null; 4180 } 4181 4182 @Override 4183 public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) { 4184 if (!sUserManager.exists(userId)) return null; 4185 Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0"); 4186 4187 flags = updateFlagsForPackage(flags, userId, null); 4188 4189 final boolean canSeeStaticLibraries = 4190 mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES) 4191 == PERMISSION_GRANTED 4192 || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES) 4193 == PERMISSION_GRANTED 4194 || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES) 4195 == PERMISSION_GRANTED 4196 || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES) 4197 == PERMISSION_GRANTED; 4198 4199 synchronized (mPackages) { 4200 List<SharedLibraryInfo> result = null; 4201 4202 final int libCount = mSharedLibraries.size(); 4203 for (int i = 0; i < libCount; i++) { 4204 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 4205 if (versionedLib == null) { 4206 continue; 4207 } 4208 4209 final int versionCount = versionedLib.size(); 4210 for (int j = 0; j < versionCount; j++) { 4211 SharedLibraryInfo libInfo = versionedLib.valueAt(j).info; 4212 if (!canSeeStaticLibraries && libInfo.isStatic()) { 4213 break; 4214 } 4215 final long identity = Binder.clearCallingIdentity(); 4216 try { 4217 // TODO: We will change version code to long, so in the new API it is long 4218 PackageInfo packageInfo = getPackageInfoVersioned( 4219 libInfo.getDeclaringPackage(), flags, userId); 4220 if (packageInfo == null) { 4221 continue; 4222 } 4223 } finally { 4224 Binder.restoreCallingIdentity(identity); 4225 } 4226 4227 SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(), 4228 libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(), 4229 getPackagesUsingSharedLibraryLPr(libInfo, flags, userId)); 4230 4231 if (result == null) { 4232 result = new ArrayList<>(); 4233 } 4234 result.add(resLibInfo); 4235 } 4236 } 4237 4238 return result != null ? new ParceledListSlice<>(result) : null; 4239 } 4240 } 4241 4242 private List<VersionedPackage> getPackagesUsingSharedLibraryLPr( 4243 SharedLibraryInfo libInfo, int flags, int userId) { 4244 List<VersionedPackage> versionedPackages = null; 4245 final int packageCount = mSettings.mPackages.size(); 4246 for (int i = 0; i < packageCount; i++) { 4247 PackageSetting ps = mSettings.mPackages.valueAt(i); 4248 4249 if (ps == null) { 4250 continue; 4251 } 4252 4253 if (!ps.getUserState().get(userId).isAvailable(flags)) { 4254 continue; 4255 } 4256 4257 final String libName = libInfo.getName(); 4258 if (libInfo.isStatic()) { 4259 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName); 4260 if (libIdx < 0) { 4261 continue; 4262 } 4263 if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) { 4264 continue; 4265 } 4266 if (versionedPackages == null) { 4267 versionedPackages = new ArrayList<>(); 4268 } 4269 // If the dependent is a static shared lib, use the public package name 4270 String dependentPackageName = ps.name; 4271 if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) { 4272 dependentPackageName = ps.pkg.manifestPackageName; 4273 } 4274 versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode)); 4275 } else if (ps.pkg != null) { 4276 if (ArrayUtils.contains(ps.pkg.usesLibraries, libName) 4277 || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) { 4278 if (versionedPackages == null) { 4279 versionedPackages = new ArrayList<>(); 4280 } 4281 versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode)); 4282 } 4283 } 4284 } 4285 4286 return versionedPackages; 4287 } 4288 4289 @Override 4290 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 4291 if (!sUserManager.exists(userId)) return null; 4292 flags = updateFlagsForComponent(flags, userId, component); 4293 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4294 false /* requireFullPermission */, false /* checkShell */, "get service info"); 4295 synchronized (mPackages) { 4296 PackageParser.Service s = mServices.mServices.get(component); 4297 if (DEBUG_PACKAGE_INFO) Log.v( 4298 TAG, "getServiceInfo " + component + ": " + s); 4299 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 4300 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4301 if (ps == null) return null; 4302 ServiceInfo si = PackageParser.generateServiceInfo(s, flags, 4303 ps.readUserState(userId), userId); 4304 if (si != null) { 4305 rebaseEnabledOverlays(si.applicationInfo, userId); 4306 } 4307 return si; 4308 } 4309 } 4310 return null; 4311 } 4312 4313 @Override 4314 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 4315 if (!sUserManager.exists(userId)) return null; 4316 flags = updateFlagsForComponent(flags, userId, component); 4317 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4318 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 4319 synchronized (mPackages) { 4320 PackageParser.Provider p = mProviders.mProviders.get(component); 4321 if (DEBUG_PACKAGE_INFO) Log.v( 4322 TAG, "getProviderInfo " + component + ": " + p); 4323 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 4324 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 4325 if (ps == null) return null; 4326 ProviderInfo pi = PackageParser.generateProviderInfo(p, flags, 4327 ps.readUserState(userId), userId); 4328 if (pi != null) { 4329 rebaseEnabledOverlays(pi.applicationInfo, userId); 4330 } 4331 return pi; 4332 } 4333 } 4334 return null; 4335 } 4336 4337 @Override 4338 public String[] getSystemSharedLibraryNames() { 4339 synchronized (mPackages) { 4340 Set<String> libs = null; 4341 final int libCount = mSharedLibraries.size(); 4342 for (int i = 0; i < libCount; i++) { 4343 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i); 4344 if (versionedLib == null) { 4345 continue; 4346 } 4347 final int versionCount = versionedLib.size(); 4348 for (int j = 0; j < versionCount; j++) { 4349 SharedLibraryEntry libEntry = versionedLib.valueAt(j); 4350 if (!libEntry.info.isStatic()) { 4351 if (libs == null) { 4352 libs = new ArraySet<>(); 4353 } 4354 libs.add(libEntry.info.getName()); 4355 break; 4356 } 4357 PackageSetting ps = mSettings.getPackageLPr(libEntry.apk); 4358 if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(), 4359 UserHandle.getUserId(Binder.getCallingUid()))) { 4360 if (libs == null) { 4361 libs = new ArraySet<>(); 4362 } 4363 libs.add(libEntry.info.getName()); 4364 break; 4365 } 4366 } 4367 } 4368 4369 if (libs != null) { 4370 String[] libsArray = new String[libs.size()]; 4371 libs.toArray(libsArray); 4372 return libsArray; 4373 } 4374 4375 return null; 4376 } 4377 } 4378 4379 @Override 4380 public @NonNull String getServicesSystemSharedLibraryPackageName() { 4381 synchronized (mPackages) { 4382 return mServicesSystemSharedLibraryPackageName; 4383 } 4384 } 4385 4386 @Override 4387 public @NonNull String getSharedSystemSharedLibraryPackageName() { 4388 synchronized (mPackages) { 4389 return mSharedSystemSharedLibraryPackageName; 4390 } 4391 } 4392 4393 private void updateSequenceNumberLP(String packageName, int[] userList) { 4394 for (int i = userList.length - 1; i >= 0; --i) { 4395 final int userId = userList[i]; 4396 SparseArray<String> changedPackages = mChangedPackages.get(userId); 4397 if (changedPackages == null) { 4398 changedPackages = new SparseArray<>(); 4399 mChangedPackages.put(userId, changedPackages); 4400 } 4401 Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId); 4402 if (sequenceNumbers == null) { 4403 sequenceNumbers = new HashMap<>(); 4404 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers); 4405 } 4406 final Integer sequenceNumber = sequenceNumbers.get(packageName); 4407 if (sequenceNumber != null) { 4408 changedPackages.remove(sequenceNumber); 4409 } 4410 changedPackages.put(mChangedPackagesSequenceNumber, packageName); 4411 sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber); 4412 } 4413 mChangedPackagesSequenceNumber++; 4414 } 4415 4416 @Override 4417 public ChangedPackages getChangedPackages(int sequenceNumber, int userId) { 4418 synchronized (mPackages) { 4419 if (sequenceNumber >= mChangedPackagesSequenceNumber) { 4420 return null; 4421 } 4422 final SparseArray<String> changedPackages = mChangedPackages.get(userId); 4423 if (changedPackages == null) { 4424 return null; 4425 } 4426 final List<String> packageNames = 4427 new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber); 4428 for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) { 4429 final String packageName = changedPackages.get(i); 4430 if (packageName != null) { 4431 packageNames.add(packageName); 4432 } 4433 } 4434 return packageNames.isEmpty() 4435 ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames); 4436 } 4437 } 4438 4439 @Override 4440 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 4441 ArrayList<FeatureInfo> res; 4442 synchronized (mAvailableFeatures) { 4443 res = new ArrayList<>(mAvailableFeatures.size() + 1); 4444 res.addAll(mAvailableFeatures.values()); 4445 } 4446 final FeatureInfo fi = new FeatureInfo(); 4447 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 4448 FeatureInfo.GL_ES_VERSION_UNDEFINED); 4449 res.add(fi); 4450 4451 return new ParceledListSlice<>(res); 4452 } 4453 4454 @Override 4455 public boolean hasSystemFeature(String name, int version) { 4456 synchronized (mAvailableFeatures) { 4457 final FeatureInfo feat = mAvailableFeatures.get(name); 4458 if (feat == null) { 4459 return false; 4460 } else { 4461 return feat.version >= version; 4462 } 4463 } 4464 } 4465 4466 @Override 4467 public int checkPermission(String permName, String pkgName, int userId) { 4468 if (!sUserManager.exists(userId)) { 4469 return PackageManager.PERMISSION_DENIED; 4470 } 4471 4472 synchronized (mPackages) { 4473 final PackageParser.Package p = mPackages.get(pkgName); 4474 if (p != null && p.mExtras != null) { 4475 final PackageSetting ps = (PackageSetting) p.mExtras; 4476 final PermissionsState permissionsState = ps.getPermissionsState(); 4477 if (permissionsState.hasPermission(permName, userId)) { 4478 return PackageManager.PERMISSION_GRANTED; 4479 } 4480 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 4481 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 4482 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 4483 return PackageManager.PERMISSION_GRANTED; 4484 } 4485 } 4486 } 4487 4488 return PackageManager.PERMISSION_DENIED; 4489 } 4490 4491 @Override 4492 public int checkUidPermission(String permName, int uid) { 4493 final int userId = UserHandle.getUserId(uid); 4494 4495 if (!sUserManager.exists(userId)) { 4496 return PackageManager.PERMISSION_DENIED; 4497 } 4498 4499 synchronized (mPackages) { 4500 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4501 if (obj != null) { 4502 final SettingBase ps = (SettingBase) obj; 4503 final PermissionsState permissionsState = ps.getPermissionsState(); 4504 if (permissionsState.hasPermission(permName, userId)) { 4505 return PackageManager.PERMISSION_GRANTED; 4506 } 4507 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 4508 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 4509 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 4510 return PackageManager.PERMISSION_GRANTED; 4511 } 4512 } else { 4513 ArraySet<String> perms = mSystemPermissions.get(uid); 4514 if (perms != null) { 4515 if (perms.contains(permName)) { 4516 return PackageManager.PERMISSION_GRANTED; 4517 } 4518 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 4519 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 4520 return PackageManager.PERMISSION_GRANTED; 4521 } 4522 } 4523 } 4524 } 4525 4526 return PackageManager.PERMISSION_DENIED; 4527 } 4528 4529 @Override 4530 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 4531 if (UserHandle.getCallingUserId() != userId) { 4532 mContext.enforceCallingPermission( 4533 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4534 "isPermissionRevokedByPolicy for user " + userId); 4535 } 4536 4537 if (checkPermission(permission, packageName, userId) 4538 == PackageManager.PERMISSION_GRANTED) { 4539 return false; 4540 } 4541 4542 final long identity = Binder.clearCallingIdentity(); 4543 try { 4544 final int flags = getPermissionFlags(permission, packageName, userId); 4545 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 4546 } finally { 4547 Binder.restoreCallingIdentity(identity); 4548 } 4549 } 4550 4551 @Override 4552 public String getPermissionControllerPackageName() { 4553 synchronized (mPackages) { 4554 return mRequiredInstallerPackage; 4555 } 4556 } 4557 4558 /** 4559 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 4560 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 4561 * @param checkShell whether to prevent shell from access if there's a debugging restriction 4562 * @param message the message to log on security exception 4563 */ 4564 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 4565 boolean checkShell, String message) { 4566 if (userId < 0) { 4567 throw new IllegalArgumentException("Invalid userId " + userId); 4568 } 4569 if (checkShell) { 4570 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 4571 } 4572 if (userId == UserHandle.getUserId(callingUid)) return; 4573 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4574 if (requireFullPermission) { 4575 mContext.enforceCallingOrSelfPermission( 4576 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 4577 } else { 4578 try { 4579 mContext.enforceCallingOrSelfPermission( 4580 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 4581 } catch (SecurityException se) { 4582 mContext.enforceCallingOrSelfPermission( 4583 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 4584 } 4585 } 4586 } 4587 } 4588 4589 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 4590 if (callingUid == Process.SHELL_UID) { 4591 if (userHandle >= 0 4592 && sUserManager.hasUserRestriction(restriction, userHandle)) { 4593 throw new SecurityException("Shell does not have permission to access user " 4594 + userHandle); 4595 } else if (userHandle < 0) { 4596 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 4597 + Debug.getCallers(3)); 4598 } 4599 } 4600 } 4601 4602 private BasePermission findPermissionTreeLP(String permName) { 4603 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 4604 if (permName.startsWith(bp.name) && 4605 permName.length() > bp.name.length() && 4606 permName.charAt(bp.name.length()) == '.') { 4607 return bp; 4608 } 4609 } 4610 return null; 4611 } 4612 4613 private BasePermission checkPermissionTreeLP(String permName) { 4614 if (permName != null) { 4615 BasePermission bp = findPermissionTreeLP(permName); 4616 if (bp != null) { 4617 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 4618 return bp; 4619 } 4620 throw new SecurityException("Calling uid " 4621 + Binder.getCallingUid() 4622 + " is not allowed to add to permission tree " 4623 + bp.name + " owned by uid " + bp.uid); 4624 } 4625 } 4626 throw new SecurityException("No permission tree found for " + permName); 4627 } 4628 4629 static boolean compareStrings(CharSequence s1, CharSequence s2) { 4630 if (s1 == null) { 4631 return s2 == null; 4632 } 4633 if (s2 == null) { 4634 return false; 4635 } 4636 if (s1.getClass() != s2.getClass()) { 4637 return false; 4638 } 4639 return s1.equals(s2); 4640 } 4641 4642 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 4643 if (pi1.icon != pi2.icon) return false; 4644 if (pi1.logo != pi2.logo) return false; 4645 if (pi1.protectionLevel != pi2.protectionLevel) return false; 4646 if (!compareStrings(pi1.name, pi2.name)) return false; 4647 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 4648 // We'll take care of setting this one. 4649 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 4650 // These are not currently stored in settings. 4651 //if (!compareStrings(pi1.group, pi2.group)) return false; 4652 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 4653 //if (pi1.labelRes != pi2.labelRes) return false; 4654 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 4655 return true; 4656 } 4657 4658 int permissionInfoFootprint(PermissionInfo info) { 4659 int size = info.name.length(); 4660 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 4661 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 4662 return size; 4663 } 4664 4665 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 4666 int size = 0; 4667 for (BasePermission perm : mSettings.mPermissions.values()) { 4668 if (perm.uid == tree.uid) { 4669 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 4670 } 4671 } 4672 return size; 4673 } 4674 4675 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 4676 // We calculate the max size of permissions defined by this uid and throw 4677 // if that plus the size of 'info' would exceed our stated maximum. 4678 if (tree.uid != Process.SYSTEM_UID) { 4679 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 4680 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 4681 throw new SecurityException("Permission tree size cap exceeded"); 4682 } 4683 } 4684 } 4685 4686 boolean addPermissionLocked(PermissionInfo info, boolean async) { 4687 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 4688 throw new SecurityException("Label must be specified in permission"); 4689 } 4690 BasePermission tree = checkPermissionTreeLP(info.name); 4691 BasePermission bp = mSettings.mPermissions.get(info.name); 4692 boolean added = bp == null; 4693 boolean changed = true; 4694 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 4695 if (added) { 4696 enforcePermissionCapLocked(info, tree); 4697 bp = new BasePermission(info.name, tree.sourcePackage, 4698 BasePermission.TYPE_DYNAMIC); 4699 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 4700 throw new SecurityException( 4701 "Not allowed to modify non-dynamic permission " 4702 + info.name); 4703 } else { 4704 if (bp.protectionLevel == fixedLevel 4705 && bp.perm.owner.equals(tree.perm.owner) 4706 && bp.uid == tree.uid 4707 && comparePermissionInfos(bp.perm.info, info)) { 4708 changed = false; 4709 } 4710 } 4711 bp.protectionLevel = fixedLevel; 4712 info = new PermissionInfo(info); 4713 info.protectionLevel = fixedLevel; 4714 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 4715 bp.perm.info.packageName = tree.perm.info.packageName; 4716 bp.uid = tree.uid; 4717 if (added) { 4718 mSettings.mPermissions.put(info.name, bp); 4719 } 4720 if (changed) { 4721 if (!async) { 4722 mSettings.writeLPr(); 4723 } else { 4724 scheduleWriteSettingsLocked(); 4725 } 4726 } 4727 return added; 4728 } 4729 4730 @Override 4731 public boolean addPermission(PermissionInfo info) { 4732 synchronized (mPackages) { 4733 return addPermissionLocked(info, false); 4734 } 4735 } 4736 4737 @Override 4738 public boolean addPermissionAsync(PermissionInfo info) { 4739 synchronized (mPackages) { 4740 return addPermissionLocked(info, true); 4741 } 4742 } 4743 4744 @Override 4745 public void removePermission(String name) { 4746 synchronized (mPackages) { 4747 checkPermissionTreeLP(name); 4748 BasePermission bp = mSettings.mPermissions.get(name); 4749 if (bp != null) { 4750 if (bp.type != BasePermission.TYPE_DYNAMIC) { 4751 throw new SecurityException( 4752 "Not allowed to modify non-dynamic permission " 4753 + name); 4754 } 4755 mSettings.mPermissions.remove(name); 4756 mSettings.writeLPr(); 4757 } 4758 } 4759 } 4760 4761 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 4762 BasePermission bp) { 4763 int index = pkg.requestedPermissions.indexOf(bp.name); 4764 if (index == -1) { 4765 throw new SecurityException("Package " + pkg.packageName 4766 + " has not requested permission " + bp.name); 4767 } 4768 if (!bp.isRuntime() && !bp.isDevelopment()) { 4769 throw new SecurityException("Permission " + bp.name 4770 + " is not a changeable permission type"); 4771 } 4772 } 4773 4774 @Override 4775 public void grantRuntimePermission(String packageName, String name, final int userId) { 4776 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4777 } 4778 4779 private void grantRuntimePermission(String packageName, String name, final int userId, 4780 boolean overridePolicy) { 4781 if (!sUserManager.exists(userId)) { 4782 Log.e(TAG, "No such user:" + userId); 4783 return; 4784 } 4785 4786 mContext.enforceCallingOrSelfPermission( 4787 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 4788 "grantRuntimePermission"); 4789 4790 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4791 true /* requireFullPermission */, true /* checkShell */, 4792 "grantRuntimePermission"); 4793 4794 final int uid; 4795 final SettingBase sb; 4796 4797 synchronized (mPackages) { 4798 final PackageParser.Package pkg = mPackages.get(packageName); 4799 if (pkg == null) { 4800 throw new IllegalArgumentException("Unknown package: " + packageName); 4801 } 4802 4803 final BasePermission bp = mSettings.mPermissions.get(name); 4804 if (bp == null) { 4805 throw new IllegalArgumentException("Unknown permission: " + name); 4806 } 4807 4808 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4809 4810 // If a permission review is required for legacy apps we represent 4811 // their permissions as always granted runtime ones since we need 4812 // to keep the review required permission flag per user while an 4813 // install permission's state is shared across all users. 4814 if (mPermissionReviewRequired 4815 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4816 && bp.isRuntime()) { 4817 return; 4818 } 4819 4820 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 4821 sb = (SettingBase) pkg.mExtras; 4822 if (sb == null) { 4823 throw new IllegalArgumentException("Unknown package: " + packageName); 4824 } 4825 4826 final PermissionsState permissionsState = sb.getPermissionsState(); 4827 4828 final int flags = permissionsState.getPermissionFlags(name, userId); 4829 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4830 throw new SecurityException("Cannot grant system fixed permission " 4831 + name + " for package " + packageName); 4832 } 4833 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4834 throw new SecurityException("Cannot grant policy fixed permission " 4835 + name + " for package " + packageName); 4836 } 4837 4838 if (bp.isDevelopment()) { 4839 // Development permissions must be handled specially, since they are not 4840 // normal runtime permissions. For now they apply to all users. 4841 if (permissionsState.grantInstallPermission(bp) != 4842 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4843 scheduleWriteSettingsLocked(); 4844 } 4845 return; 4846 } 4847 4848 final PackageSetting ps = mSettings.mPackages.get(packageName); 4849 if (ps.getInstantApp(userId) && !bp.isInstant()) { 4850 throw new SecurityException("Cannot grant non-ephemeral permission" 4851 + name + " for package " + packageName); 4852 } 4853 4854 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4855 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4856 return; 4857 } 4858 4859 final int result = permissionsState.grantRuntimePermission(bp, userId); 4860 switch (result) { 4861 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4862 return; 4863 } 4864 4865 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4866 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4867 mHandler.post(new Runnable() { 4868 @Override 4869 public void run() { 4870 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4871 } 4872 }); 4873 } 4874 break; 4875 } 4876 4877 if (bp.isRuntime()) { 4878 logPermissionGranted(mContext, name, packageName); 4879 } 4880 4881 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4882 4883 // Not critical if that is lost - app has to request again. 4884 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4885 } 4886 4887 // Only need to do this if user is initialized. Otherwise it's a new user 4888 // and there are no processes running as the user yet and there's no need 4889 // to make an expensive call to remount processes for the changed permissions. 4890 if (READ_EXTERNAL_STORAGE.equals(name) 4891 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4892 final long token = Binder.clearCallingIdentity(); 4893 try { 4894 if (sUserManager.isInitialized(userId)) { 4895 StorageManagerInternal storageManagerInternal = LocalServices.getService( 4896 StorageManagerInternal.class); 4897 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName); 4898 } 4899 } finally { 4900 Binder.restoreCallingIdentity(token); 4901 } 4902 } 4903 } 4904 4905 @Override 4906 public void revokeRuntimePermission(String packageName, String name, int userId) { 4907 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4908 } 4909 4910 private void revokeRuntimePermission(String packageName, String name, int userId, 4911 boolean overridePolicy) { 4912 if (!sUserManager.exists(userId)) { 4913 Log.e(TAG, "No such user:" + userId); 4914 return; 4915 } 4916 4917 mContext.enforceCallingOrSelfPermission( 4918 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4919 "revokeRuntimePermission"); 4920 4921 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4922 true /* requireFullPermission */, true /* checkShell */, 4923 "revokeRuntimePermission"); 4924 4925 final int appId; 4926 4927 synchronized (mPackages) { 4928 final PackageParser.Package pkg = mPackages.get(packageName); 4929 if (pkg == null) { 4930 throw new IllegalArgumentException("Unknown package: " + packageName); 4931 } 4932 4933 final BasePermission bp = mSettings.mPermissions.get(name); 4934 if (bp == null) { 4935 throw new IllegalArgumentException("Unknown permission: " + name); 4936 } 4937 4938 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4939 4940 // If a permission review is required for legacy apps we represent 4941 // their permissions as always granted runtime ones since we need 4942 // to keep the review required permission flag per user while an 4943 // install permission's state is shared across all users. 4944 if (mPermissionReviewRequired 4945 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4946 && bp.isRuntime()) { 4947 return; 4948 } 4949 4950 SettingBase sb = (SettingBase) pkg.mExtras; 4951 if (sb == null) { 4952 throw new IllegalArgumentException("Unknown package: " + packageName); 4953 } 4954 4955 final PermissionsState permissionsState = sb.getPermissionsState(); 4956 4957 final int flags = permissionsState.getPermissionFlags(name, userId); 4958 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4959 throw new SecurityException("Cannot revoke system fixed permission " 4960 + name + " for package " + packageName); 4961 } 4962 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4963 throw new SecurityException("Cannot revoke policy fixed permission " 4964 + name + " for package " + packageName); 4965 } 4966 4967 if (bp.isDevelopment()) { 4968 // Development permissions must be handled specially, since they are not 4969 // normal runtime permissions. For now they apply to all users. 4970 if (permissionsState.revokeInstallPermission(bp) != 4971 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4972 scheduleWriteSettingsLocked(); 4973 } 4974 return; 4975 } 4976 4977 if (permissionsState.revokeRuntimePermission(bp, userId) == 4978 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4979 return; 4980 } 4981 4982 if (bp.isRuntime()) { 4983 logPermissionRevoked(mContext, name, packageName); 4984 } 4985 4986 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4987 4988 // Critical, after this call app should never have the permission. 4989 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4990 4991 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4992 } 4993 4994 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4995 } 4996 4997 /** 4998 * Get the first event id for the permission. 4999 * 5000 * <p>There are four events for each permission: <ul> 5001 * <li>Request permission: first id + 0</li> 5002 * <li>Grant permission: first id + 1</li> 5003 * <li>Request for permission denied: first id + 2</li> 5004 * <li>Revoke permission: first id + 3</li> 5005 * </ul></p> 5006 * 5007 * @param name name of the permission 5008 * 5009 * @return The first event id for the permission 5010 */ 5011 private static int getBaseEventId(@NonNull String name) { 5012 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name); 5013 5014 if (eventIdIndex == -1) { 5015 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE 5016 || "user".equals(Build.TYPE)) { 5017 Log.i(TAG, "Unknown permission " + name); 5018 5019 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN; 5020 } else { 5021 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated. 5022 // 5023 // Also update 5024 // - EventLogger#ALL_DANGEROUS_PERMISSIONS 5025 // - metrics_constants.proto 5026 throw new IllegalStateException("Unknown permission " + name); 5027 } 5028 } 5029 5030 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4; 5031 } 5032 5033 /** 5034 * Log that a permission was revoked. 5035 * 5036 * @param context Context of the caller 5037 * @param name name of the permission 5038 * @param packageName package permission if for 5039 */ 5040 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name, 5041 @NonNull String packageName) { 5042 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName); 5043 } 5044 5045 /** 5046 * Log that a permission request was granted. 5047 * 5048 * @param context Context of the caller 5049 * @param name name of the permission 5050 * @param packageName package permission if for 5051 */ 5052 private static void logPermissionGranted(@NonNull Context context, @NonNull String name, 5053 @NonNull String packageName) { 5054 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName); 5055 } 5056 5057 @Override 5058 public void resetRuntimePermissions() { 5059 mContext.enforceCallingOrSelfPermission( 5060 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 5061 "revokeRuntimePermission"); 5062 5063 int callingUid = Binder.getCallingUid(); 5064 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 5065 mContext.enforceCallingOrSelfPermission( 5066 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5067 "resetRuntimePermissions"); 5068 } 5069 5070 synchronized (mPackages) { 5071 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 5072 for (int userId : UserManagerService.getInstance().getUserIds()) { 5073 final int packageCount = mPackages.size(); 5074 for (int i = 0; i < packageCount; i++) { 5075 PackageParser.Package pkg = mPackages.valueAt(i); 5076 if (!(pkg.mExtras instanceof PackageSetting)) { 5077 continue; 5078 } 5079 PackageSetting ps = (PackageSetting) pkg.mExtras; 5080 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 5081 } 5082 } 5083 } 5084 } 5085 5086 @Override 5087 public int getPermissionFlags(String name, String packageName, int userId) { 5088 if (!sUserManager.exists(userId)) { 5089 return 0; 5090 } 5091 5092 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 5093 5094 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5095 true /* requireFullPermission */, false /* checkShell */, 5096 "getPermissionFlags"); 5097 5098 synchronized (mPackages) { 5099 final PackageParser.Package pkg = mPackages.get(packageName); 5100 if (pkg == null) { 5101 return 0; 5102 } 5103 5104 final BasePermission bp = mSettings.mPermissions.get(name); 5105 if (bp == null) { 5106 return 0; 5107 } 5108 5109 SettingBase sb = (SettingBase) pkg.mExtras; 5110 if (sb == null) { 5111 return 0; 5112 } 5113 5114 PermissionsState permissionsState = sb.getPermissionsState(); 5115 return permissionsState.getPermissionFlags(name, userId); 5116 } 5117 } 5118 5119 @Override 5120 public void updatePermissionFlags(String name, String packageName, int flagMask, 5121 int flagValues, int userId) { 5122 if (!sUserManager.exists(userId)) { 5123 return; 5124 } 5125 5126 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 5127 5128 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5129 true /* requireFullPermission */, true /* checkShell */, 5130 "updatePermissionFlags"); 5131 5132 // Only the system can change these flags and nothing else. 5133 if (getCallingUid() != Process.SYSTEM_UID) { 5134 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5135 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5136 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 5137 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 5138 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 5139 } 5140 5141 synchronized (mPackages) { 5142 final PackageParser.Package pkg = mPackages.get(packageName); 5143 if (pkg == null) { 5144 throw new IllegalArgumentException("Unknown package: " + packageName); 5145 } 5146 5147 final BasePermission bp = mSettings.mPermissions.get(name); 5148 if (bp == null) { 5149 throw new IllegalArgumentException("Unknown permission: " + name); 5150 } 5151 5152 SettingBase sb = (SettingBase) pkg.mExtras; 5153 if (sb == null) { 5154 throw new IllegalArgumentException("Unknown package: " + packageName); 5155 } 5156 5157 PermissionsState permissionsState = sb.getPermissionsState(); 5158 5159 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 5160 5161 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 5162 // Install and runtime permissions are stored in different places, 5163 // so figure out what permission changed and persist the change. 5164 if (permissionsState.getInstallPermissionState(name) != null) { 5165 scheduleWriteSettingsLocked(); 5166 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 5167 || hadState) { 5168 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 5169 } 5170 } 5171 } 5172 } 5173 5174 /** 5175 * Update the permission flags for all packages and runtime permissions of a user in order 5176 * to allow device or profile owner to remove POLICY_FIXED. 5177 */ 5178 @Override 5179 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 5180 if (!sUserManager.exists(userId)) { 5181 return; 5182 } 5183 5184 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 5185 5186 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5187 true /* requireFullPermission */, true /* checkShell */, 5188 "updatePermissionFlagsForAllApps"); 5189 5190 // Only the system can change system fixed flags. 5191 if (getCallingUid() != Process.SYSTEM_UID) { 5192 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5193 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 5194 } 5195 5196 synchronized (mPackages) { 5197 boolean changed = false; 5198 final int packageCount = mPackages.size(); 5199 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 5200 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 5201 SettingBase sb = (SettingBase) pkg.mExtras; 5202 if (sb == null) { 5203 continue; 5204 } 5205 PermissionsState permissionsState = sb.getPermissionsState(); 5206 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 5207 userId, flagMask, flagValues); 5208 } 5209 if (changed) { 5210 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 5211 } 5212 } 5213 } 5214 5215 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 5216 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 5217 != PackageManager.PERMISSION_GRANTED 5218 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 5219 != PackageManager.PERMISSION_GRANTED) { 5220 throw new SecurityException(message + " requires " 5221 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 5222 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 5223 } 5224 } 5225 5226 @Override 5227 public boolean shouldShowRequestPermissionRationale(String permissionName, 5228 String packageName, int userId) { 5229 if (UserHandle.getCallingUserId() != userId) { 5230 mContext.enforceCallingPermission( 5231 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 5232 "canShowRequestPermissionRationale for user " + userId); 5233 } 5234 5235 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 5236 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 5237 return false; 5238 } 5239 5240 if (checkPermission(permissionName, packageName, userId) 5241 == PackageManager.PERMISSION_GRANTED) { 5242 return false; 5243 } 5244 5245 final int flags; 5246 5247 final long identity = Binder.clearCallingIdentity(); 5248 try { 5249 flags = getPermissionFlags(permissionName, 5250 packageName, userId); 5251 } finally { 5252 Binder.restoreCallingIdentity(identity); 5253 } 5254 5255 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 5256 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 5257 | PackageManager.FLAG_PERMISSION_USER_FIXED; 5258 5259 if ((flags & fixedFlags) != 0) { 5260 return false; 5261 } 5262 5263 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 5264 } 5265 5266 @Override 5267 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 5268 mContext.enforceCallingOrSelfPermission( 5269 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 5270 "addOnPermissionsChangeListener"); 5271 5272 synchronized (mPackages) { 5273 mOnPermissionChangeListeners.addListenerLocked(listener); 5274 } 5275 } 5276 5277 @Override 5278 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 5279 synchronized (mPackages) { 5280 mOnPermissionChangeListeners.removeListenerLocked(listener); 5281 } 5282 } 5283 5284 @Override 5285 public boolean isProtectedBroadcast(String actionName) { 5286 synchronized (mPackages) { 5287 if (mProtectedBroadcasts.contains(actionName)) { 5288 return true; 5289 } else if (actionName != null) { 5290 // TODO: remove these terrible hacks 5291 if (actionName.startsWith("android.net.netmon.lingerExpired") 5292 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 5293 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 5294 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 5295 return true; 5296 } 5297 } 5298 } 5299 return false; 5300 } 5301 5302 @Override 5303 public int checkSignatures(String pkg1, String pkg2) { 5304 synchronized (mPackages) { 5305 final PackageParser.Package p1 = mPackages.get(pkg1); 5306 final PackageParser.Package p2 = mPackages.get(pkg2); 5307 if (p1 == null || p1.mExtras == null 5308 || p2 == null || p2.mExtras == null) { 5309 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5310 } 5311 return compareSignatures(p1.mSignatures, p2.mSignatures); 5312 } 5313 } 5314 5315 @Override 5316 public int checkUidSignatures(int uid1, int uid2) { 5317 // Map to base uids. 5318 uid1 = UserHandle.getAppId(uid1); 5319 uid2 = UserHandle.getAppId(uid2); 5320 // reader 5321 synchronized (mPackages) { 5322 Signature[] s1; 5323 Signature[] s2; 5324 Object obj = mSettings.getUserIdLPr(uid1); 5325 if (obj != null) { 5326 if (obj instanceof SharedUserSetting) { 5327 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 5328 } else if (obj instanceof PackageSetting) { 5329 s1 = ((PackageSetting)obj).signatures.mSignatures; 5330 } else { 5331 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5332 } 5333 } else { 5334 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5335 } 5336 obj = mSettings.getUserIdLPr(uid2); 5337 if (obj != null) { 5338 if (obj instanceof SharedUserSetting) { 5339 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 5340 } else if (obj instanceof PackageSetting) { 5341 s2 = ((PackageSetting)obj).signatures.mSignatures; 5342 } else { 5343 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5344 } 5345 } else { 5346 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 5347 } 5348 return compareSignatures(s1, s2); 5349 } 5350 } 5351 5352 /** 5353 * This method should typically only be used when granting or revoking 5354 * permissions, since the app may immediately restart after this call. 5355 * <p> 5356 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 5357 * guard your work against the app being relaunched. 5358 */ 5359 private void killUid(int appId, int userId, String reason) { 5360 final long identity = Binder.clearCallingIdentity(); 5361 try { 5362 IActivityManager am = ActivityManager.getService(); 5363 if (am != null) { 5364 try { 5365 am.killUid(appId, userId, reason); 5366 } catch (RemoteException e) { 5367 /* ignore - same process */ 5368 } 5369 } 5370 } finally { 5371 Binder.restoreCallingIdentity(identity); 5372 } 5373 } 5374 5375 /** 5376 * Compares two sets of signatures. Returns: 5377 * <br /> 5378 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 5379 * <br /> 5380 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 5381 * <br /> 5382 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 5383 * <br /> 5384 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 5385 * <br /> 5386 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 5387 */ 5388 static int compareSignatures(Signature[] s1, Signature[] s2) { 5389 if (s1 == null) { 5390 return s2 == null 5391 ? PackageManager.SIGNATURE_NEITHER_SIGNED 5392 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 5393 } 5394 5395 if (s2 == null) { 5396 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 5397 } 5398 5399 if (s1.length != s2.length) { 5400 return PackageManager.SIGNATURE_NO_MATCH; 5401 } 5402 5403 // Since both signature sets are of size 1, we can compare without HashSets. 5404 if (s1.length == 1) { 5405 return s1[0].equals(s2[0]) ? 5406 PackageManager.SIGNATURE_MATCH : 5407 PackageManager.SIGNATURE_NO_MATCH; 5408 } 5409 5410 ArraySet<Signature> set1 = new ArraySet<Signature>(); 5411 for (Signature sig : s1) { 5412 set1.add(sig); 5413 } 5414 ArraySet<Signature> set2 = new ArraySet<Signature>(); 5415 for (Signature sig : s2) { 5416 set2.add(sig); 5417 } 5418 // Make sure s2 contains all signatures in s1. 5419 if (set1.equals(set2)) { 5420 return PackageManager.SIGNATURE_MATCH; 5421 } 5422 return PackageManager.SIGNATURE_NO_MATCH; 5423 } 5424 5425 /** 5426 * If the database version for this type of package (internal storage or 5427 * external storage) is less than the version where package signatures 5428 * were updated, return true. 5429 */ 5430 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 5431 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 5432 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 5433 } 5434 5435 /** 5436 * Used for backward compatibility to make sure any packages with 5437 * certificate chains get upgraded to the new style. {@code existingSigs} 5438 * will be in the old format (since they were stored on disk from before the 5439 * system upgrade) and {@code scannedSigs} will be in the newer format. 5440 */ 5441 private int compareSignaturesCompat(PackageSignatures existingSigs, 5442 PackageParser.Package scannedPkg) { 5443 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 5444 return PackageManager.SIGNATURE_NO_MATCH; 5445 } 5446 5447 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 5448 for (Signature sig : existingSigs.mSignatures) { 5449 existingSet.add(sig); 5450 } 5451 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 5452 for (Signature sig : scannedPkg.mSignatures) { 5453 try { 5454 Signature[] chainSignatures = sig.getChainSignatures(); 5455 for (Signature chainSig : chainSignatures) { 5456 scannedCompatSet.add(chainSig); 5457 } 5458 } catch (CertificateEncodingException e) { 5459 scannedCompatSet.add(sig); 5460 } 5461 } 5462 /* 5463 * Make sure the expanded scanned set contains all signatures in the 5464 * existing one. 5465 */ 5466 if (scannedCompatSet.equals(existingSet)) { 5467 // Migrate the old signatures to the new scheme. 5468 existingSigs.assignSignatures(scannedPkg.mSignatures); 5469 // The new KeySets will be re-added later in the scanning process. 5470 synchronized (mPackages) { 5471 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 5472 } 5473 return PackageManager.SIGNATURE_MATCH; 5474 } 5475 return PackageManager.SIGNATURE_NO_MATCH; 5476 } 5477 5478 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 5479 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 5480 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 5481 } 5482 5483 private int compareSignaturesRecover(PackageSignatures existingSigs, 5484 PackageParser.Package scannedPkg) { 5485 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 5486 return PackageManager.SIGNATURE_NO_MATCH; 5487 } 5488 5489 String msg = null; 5490 try { 5491 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 5492 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 5493 + scannedPkg.packageName); 5494 return PackageManager.SIGNATURE_MATCH; 5495 } 5496 } catch (CertificateException e) { 5497 msg = e.getMessage(); 5498 } 5499 5500 logCriticalInfo(Log.INFO, 5501 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 5502 return PackageManager.SIGNATURE_NO_MATCH; 5503 } 5504 5505 @Override 5506 public List<String> getAllPackages() { 5507 synchronized (mPackages) { 5508 return new ArrayList<String>(mPackages.keySet()); 5509 } 5510 } 5511 5512 @Override 5513 public String[] getPackagesForUid(int uid) { 5514 final int userId = UserHandle.getUserId(uid); 5515 uid = UserHandle.getAppId(uid); 5516 // reader 5517 synchronized (mPackages) { 5518 Object obj = mSettings.getUserIdLPr(uid); 5519 if (obj instanceof SharedUserSetting) { 5520 final SharedUserSetting sus = (SharedUserSetting) obj; 5521 final int N = sus.packages.size(); 5522 String[] res = new String[N]; 5523 final Iterator<PackageSetting> it = sus.packages.iterator(); 5524 int i = 0; 5525 while (it.hasNext()) { 5526 PackageSetting ps = it.next(); 5527 if (ps.getInstalled(userId)) { 5528 res[i++] = ps.name; 5529 } else { 5530 res = ArrayUtils.removeElement(String.class, res, res[i]); 5531 } 5532 } 5533 return res; 5534 } else if (obj instanceof PackageSetting) { 5535 final PackageSetting ps = (PackageSetting) obj; 5536 if (ps.getInstalled(userId)) { 5537 return new String[]{ps.name}; 5538 } 5539 } 5540 } 5541 return null; 5542 } 5543 5544 @Override 5545 public String getNameForUid(int uid) { 5546 // reader 5547 synchronized (mPackages) { 5548 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5549 if (obj instanceof SharedUserSetting) { 5550 final SharedUserSetting sus = (SharedUserSetting) obj; 5551 return sus.name + ":" + sus.userId; 5552 } else if (obj instanceof PackageSetting) { 5553 final PackageSetting ps = (PackageSetting) obj; 5554 return ps.name; 5555 } 5556 } 5557 return null; 5558 } 5559 5560 @Override 5561 public int getUidForSharedUser(String sharedUserName) { 5562 if(sharedUserName == null) { 5563 return -1; 5564 } 5565 // reader 5566 synchronized (mPackages) { 5567 SharedUserSetting suid; 5568 try { 5569 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 5570 if (suid != null) { 5571 return suid.userId; 5572 } 5573 } catch (PackageManagerException ignore) { 5574 // can't happen, but, still need to catch it 5575 } 5576 return -1; 5577 } 5578 } 5579 5580 @Override 5581 public int getFlagsForUid(int uid) { 5582 synchronized (mPackages) { 5583 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5584 if (obj instanceof SharedUserSetting) { 5585 final SharedUserSetting sus = (SharedUserSetting) obj; 5586 return sus.pkgFlags; 5587 } else if (obj instanceof PackageSetting) { 5588 final PackageSetting ps = (PackageSetting) obj; 5589 return ps.pkgFlags; 5590 } 5591 } 5592 return 0; 5593 } 5594 5595 @Override 5596 public int getPrivateFlagsForUid(int uid) { 5597 synchronized (mPackages) { 5598 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5599 if (obj instanceof SharedUserSetting) { 5600 final SharedUserSetting sus = (SharedUserSetting) obj; 5601 return sus.pkgPrivateFlags; 5602 } else if (obj instanceof PackageSetting) { 5603 final PackageSetting ps = (PackageSetting) obj; 5604 return ps.pkgPrivateFlags; 5605 } 5606 } 5607 return 0; 5608 } 5609 5610 @Override 5611 public boolean isUidPrivileged(int uid) { 5612 uid = UserHandle.getAppId(uid); 5613 // reader 5614 synchronized (mPackages) { 5615 Object obj = mSettings.getUserIdLPr(uid); 5616 if (obj instanceof SharedUserSetting) { 5617 final SharedUserSetting sus = (SharedUserSetting) obj; 5618 final Iterator<PackageSetting> it = sus.packages.iterator(); 5619 while (it.hasNext()) { 5620 if (it.next().isPrivileged()) { 5621 return true; 5622 } 5623 } 5624 } else if (obj instanceof PackageSetting) { 5625 final PackageSetting ps = (PackageSetting) obj; 5626 return ps.isPrivileged(); 5627 } 5628 } 5629 return false; 5630 } 5631 5632 @Override 5633 public String[] getAppOpPermissionPackages(String permissionName) { 5634 synchronized (mPackages) { 5635 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 5636 if (pkgs == null) { 5637 return null; 5638 } 5639 return pkgs.toArray(new String[pkgs.size()]); 5640 } 5641 } 5642 5643 @Override 5644 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 5645 int flags, int userId) { 5646 return resolveIntentInternal( 5647 intent, resolvedType, flags, userId, false /*includeInstantApp*/); 5648 } 5649 5650 private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, 5651 int flags, int userId, boolean includeInstantApp) { 5652 try { 5653 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 5654 5655 if (!sUserManager.exists(userId)) return null; 5656 flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp); 5657 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5658 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 5659 5660 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5661 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 5662 flags, userId, includeInstantApp); 5663 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5664 5665 final ResolveInfo bestChoice = 5666 chooseBestActivity(intent, resolvedType, flags, query, userId); 5667 return bestChoice; 5668 } finally { 5669 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5670 } 5671 } 5672 5673 @Override 5674 public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) { 5675 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) { 5676 throw new SecurityException( 5677 "findPersistentPreferredActivity can only be run by the system"); 5678 } 5679 if (!sUserManager.exists(userId)) { 5680 return null; 5681 } 5682 intent = updateIntentForResolve(intent); 5683 final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver()); 5684 final int flags = updateFlagsForResolve(0, userId, intent, false); 5685 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5686 userId); 5687 synchronized (mPackages) { 5688 return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false, 5689 userId); 5690 } 5691 } 5692 5693 @Override 5694 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 5695 IntentFilter filter, int match, ComponentName activity) { 5696 final int userId = UserHandle.getCallingUserId(); 5697 if (DEBUG_PREFERRED) { 5698 Log.v(TAG, "setLastChosenActivity intent=" + intent 5699 + " resolvedType=" + resolvedType 5700 + " flags=" + flags 5701 + " filter=" + filter 5702 + " match=" + match 5703 + " activity=" + activity); 5704 filter.dump(new PrintStreamPrinter(System.out), " "); 5705 } 5706 intent.setComponent(null); 5707 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5708 userId); 5709 // Find any earlier preferred or last chosen entries and nuke them 5710 findPreferredActivity(intent, resolvedType, 5711 flags, query, 0, false, true, false, userId); 5712 // Add the new activity as the last chosen for this filter 5713 addPreferredActivityInternal(filter, match, null, activity, false, userId, 5714 "Setting last chosen"); 5715 } 5716 5717 @Override 5718 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 5719 final int userId = UserHandle.getCallingUserId(); 5720 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 5721 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5722 userId); 5723 return findPreferredActivity(intent, resolvedType, flags, query, 0, 5724 false, false, false, userId); 5725 } 5726 5727 /** 5728 * Returns whether or not instant apps have been disabled remotely. 5729 * <p><em>IMPORTANT</em> This should not be called with the package manager lock 5730 * held. Otherwise we run the risk of deadlock. 5731 */ 5732 private boolean isEphemeralDisabled() { 5733 // ephemeral apps have been disabled across the board 5734 if (DISABLE_EPHEMERAL_APPS) { 5735 return true; 5736 } 5737 // system isn't up yet; can't read settings, so, assume no ephemeral apps 5738 if (!mSystemReady) { 5739 return true; 5740 } 5741 // we can't get a content resolver until the system is ready; these checks must happen last 5742 final ContentResolver resolver = mContext.getContentResolver(); 5743 if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) { 5744 return true; 5745 } 5746 return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0; 5747 } 5748 5749 private boolean isEphemeralAllowed( 5750 Intent intent, List<ResolveInfo> resolvedActivities, int userId, 5751 boolean skipPackageCheck) { 5752 final int callingUser = UserHandle.getCallingUserId(); 5753 if (callingUser != UserHandle.USER_SYSTEM) { 5754 return false; 5755 } 5756 if (mInstantAppResolverConnection == null) { 5757 return false; 5758 } 5759 if (mInstantAppInstallerComponent == null) { 5760 return false; 5761 } 5762 if (intent.getComponent() != null) { 5763 return false; 5764 } 5765 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) { 5766 return false; 5767 } 5768 if (!skipPackageCheck && intent.getPackage() != null) { 5769 return false; 5770 } 5771 final boolean isWebUri = hasWebURI(intent); 5772 if (!isWebUri || intent.getData().getHost() == null) { 5773 return false; 5774 } 5775 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 5776 // Or if there's already an ephemeral app installed that handles the action 5777 synchronized (mPackages) { 5778 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); 5779 for (int n = 0; n < count; n++) { 5780 ResolveInfo info = resolvedActivities.get(n); 5781 String packageName = info.activityInfo.packageName; 5782 PackageSetting ps = mSettings.mPackages.get(packageName); 5783 if (ps != null) { 5784 // Try to get the status from User settings first 5785 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5786 int status = (int) (packedStatus >> 32); 5787 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 5788 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5789 if (DEBUG_EPHEMERAL) { 5790 Slog.v(TAG, "DENY ephemeral apps;" 5791 + " pkg: " + packageName + ", status: " + status); 5792 } 5793 return false; 5794 } 5795 if (ps.getInstantApp(userId)) { 5796 return false; 5797 } 5798 } 5799 } 5800 } 5801 // We've exhausted all ways to deny ephemeral application; let the system look for them. 5802 return true; 5803 } 5804 5805 private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, 5806 Intent origIntent, String resolvedType, String callingPackage, 5807 int userId) { 5808 final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO, 5809 new InstantAppRequest(responseObj, origIntent, resolvedType, 5810 callingPackage, userId)); 5811 mHandler.sendMessage(msg); 5812 } 5813 5814 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 5815 int flags, List<ResolveInfo> query, int userId) { 5816 if (query != null) { 5817 final int N = query.size(); 5818 if (N == 1) { 5819 return query.get(0); 5820 } else if (N > 1) { 5821 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 5822 // If there is more than one activity with the same priority, 5823 // then let the user decide between them. 5824 ResolveInfo r0 = query.get(0); 5825 ResolveInfo r1 = query.get(1); 5826 if (DEBUG_INTENT_MATCHING || debug) { 5827 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 5828 + r1.activityInfo.name + "=" + r1.priority); 5829 } 5830 // If the first activity has a higher priority, or a different 5831 // default, then it is always desirable to pick it. 5832 if (r0.priority != r1.priority 5833 || r0.preferredOrder != r1.preferredOrder 5834 || r0.isDefault != r1.isDefault) { 5835 return query.get(0); 5836 } 5837 // If we have saved a preference for a preferred activity for 5838 // this Intent, use that. 5839 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 5840 flags, query, r0.priority, true, false, debug, userId); 5841 if (ri != null) { 5842 return ri; 5843 } 5844 // If we have an ephemeral app, use it 5845 for (int i = 0; i < N; i++) { 5846 ri = query.get(i); 5847 if (ri.activityInfo.applicationInfo.isInstantApp()) { 5848 return ri; 5849 } 5850 } 5851 ri = new ResolveInfo(mResolveInfo); 5852 ri.activityInfo = new ActivityInfo(ri.activityInfo); 5853 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 5854 // If all of the options come from the same package, show the application's 5855 // label and icon instead of the generic resolver's. 5856 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 5857 // and then throw away the ResolveInfo itself, meaning that the caller loses 5858 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 5859 // a fallback for this case; we only set the target package's resources on 5860 // the ResolveInfo, not the ActivityInfo. 5861 final String intentPackage = intent.getPackage(); 5862 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 5863 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 5864 ri.resolvePackageName = intentPackage; 5865 if (userNeedsBadging(userId)) { 5866 ri.noResourceId = true; 5867 } else { 5868 ri.icon = appi.icon; 5869 } 5870 ri.iconResourceId = appi.icon; 5871 ri.labelRes = appi.labelRes; 5872 } 5873 ri.activityInfo.applicationInfo = new ApplicationInfo( 5874 ri.activityInfo.applicationInfo); 5875 if (userId != 0) { 5876 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 5877 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 5878 } 5879 // Make sure that the resolver is displayable in car mode 5880 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 5881 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 5882 return ri; 5883 } 5884 } 5885 return null; 5886 } 5887 5888 /** 5889 * Return true if the given list is not empty and all of its contents have 5890 * an activityInfo with the given package name. 5891 */ 5892 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 5893 if (ArrayUtils.isEmpty(list)) { 5894 return false; 5895 } 5896 for (int i = 0, N = list.size(); i < N; i++) { 5897 final ResolveInfo ri = list.get(i); 5898 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 5899 if (ai == null || !packageName.equals(ai.packageName)) { 5900 return false; 5901 } 5902 } 5903 return true; 5904 } 5905 5906 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 5907 int flags, List<ResolveInfo> query, boolean debug, int userId) { 5908 final int N = query.size(); 5909 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 5910 .get(userId); 5911 // Get the list of persistent preferred activities that handle the intent 5912 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 5913 List<PersistentPreferredActivity> pprefs = ppir != null 5914 ? ppir.queryIntent(intent, resolvedType, 5915 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5916 userId) 5917 : null; 5918 if (pprefs != null && pprefs.size() > 0) { 5919 final int M = pprefs.size(); 5920 for (int i=0; i<M; i++) { 5921 final PersistentPreferredActivity ppa = pprefs.get(i); 5922 if (DEBUG_PREFERRED || debug) { 5923 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 5924 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 5925 + "\n component=" + ppa.mComponent); 5926 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5927 } 5928 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 5929 flags | MATCH_DISABLED_COMPONENTS, userId); 5930 if (DEBUG_PREFERRED || debug) { 5931 Slog.v(TAG, "Found persistent preferred activity:"); 5932 if (ai != null) { 5933 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5934 } else { 5935 Slog.v(TAG, " null"); 5936 } 5937 } 5938 if (ai == null) { 5939 // This previously registered persistent preferred activity 5940 // component is no longer known. Ignore it and do NOT remove it. 5941 continue; 5942 } 5943 for (int j=0; j<N; j++) { 5944 final ResolveInfo ri = query.get(j); 5945 if (!ri.activityInfo.applicationInfo.packageName 5946 .equals(ai.applicationInfo.packageName)) { 5947 continue; 5948 } 5949 if (!ri.activityInfo.name.equals(ai.name)) { 5950 continue; 5951 } 5952 // Found a persistent preference that can handle the intent. 5953 if (DEBUG_PREFERRED || debug) { 5954 Slog.v(TAG, "Returning persistent preferred activity: " + 5955 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5956 } 5957 return ri; 5958 } 5959 } 5960 } 5961 return null; 5962 } 5963 5964 // TODO: handle preferred activities missing while user has amnesia 5965 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5966 List<ResolveInfo> query, int priority, boolean always, 5967 boolean removeMatches, boolean debug, int userId) { 5968 if (!sUserManager.exists(userId)) return null; 5969 flags = updateFlagsForResolve(flags, userId, intent, false); 5970 intent = updateIntentForResolve(intent); 5971 // writer 5972 synchronized (mPackages) { 5973 // Try to find a matching persistent preferred activity. 5974 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5975 debug, userId); 5976 5977 // If a persistent preferred activity matched, use it. 5978 if (pri != null) { 5979 return pri; 5980 } 5981 5982 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5983 // Get the list of preferred activities that handle the intent 5984 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5985 List<PreferredActivity> prefs = pir != null 5986 ? pir.queryIntent(intent, resolvedType, 5987 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5988 userId) 5989 : null; 5990 if (prefs != null && prefs.size() > 0) { 5991 boolean changed = false; 5992 try { 5993 // First figure out how good the original match set is. 5994 // We will only allow preferred activities that came 5995 // from the same match quality. 5996 int match = 0; 5997 5998 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5999 6000 final int N = query.size(); 6001 for (int j=0; j<N; j++) { 6002 final ResolveInfo ri = query.get(j); 6003 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 6004 + ": 0x" + Integer.toHexString(match)); 6005 if (ri.match > match) { 6006 match = ri.match; 6007 } 6008 } 6009 6010 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 6011 + Integer.toHexString(match)); 6012 6013 match &= IntentFilter.MATCH_CATEGORY_MASK; 6014 final int M = prefs.size(); 6015 for (int i=0; i<M; i++) { 6016 final PreferredActivity pa = prefs.get(i); 6017 if (DEBUG_PREFERRED || debug) { 6018 Slog.v(TAG, "Checking PreferredActivity ds=" 6019 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 6020 + "\n component=" + pa.mPref.mComponent); 6021 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 6022 } 6023 if (pa.mPref.mMatch != match) { 6024 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 6025 + Integer.toHexString(pa.mPref.mMatch)); 6026 continue; 6027 } 6028 // If it's not an "always" type preferred activity and that's what we're 6029 // looking for, skip it. 6030 if (always && !pa.mPref.mAlways) { 6031 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 6032 continue; 6033 } 6034 final ActivityInfo ai = getActivityInfo( 6035 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 6036 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 6037 userId); 6038 if (DEBUG_PREFERRED || debug) { 6039 Slog.v(TAG, "Found preferred activity:"); 6040 if (ai != null) { 6041 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 6042 } else { 6043 Slog.v(TAG, " null"); 6044 } 6045 } 6046 if (ai == null) { 6047 // This previously registered preferred activity 6048 // component is no longer known. Most likely an update 6049 // to the app was installed and in the new version this 6050 // component no longer exists. Clean it up by removing 6051 // it from the preferred activities list, and skip it. 6052 Slog.w(TAG, "Removing dangling preferred activity: " 6053 + pa.mPref.mComponent); 6054 pir.removeFilter(pa); 6055 changed = true; 6056 continue; 6057 } 6058 for (int j=0; j<N; j++) { 6059 final ResolveInfo ri = query.get(j); 6060 if (!ri.activityInfo.applicationInfo.packageName 6061 .equals(ai.applicationInfo.packageName)) { 6062 continue; 6063 } 6064 if (!ri.activityInfo.name.equals(ai.name)) { 6065 continue; 6066 } 6067 6068 if (removeMatches) { 6069 pir.removeFilter(pa); 6070 changed = true; 6071 if (DEBUG_PREFERRED) { 6072 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 6073 } 6074 break; 6075 } 6076 6077 // Okay we found a previously set preferred or last chosen app. 6078 // If the result set is different from when this 6079 // was created, we need to clear it and re-ask the 6080 // user their preference, if we're looking for an "always" type entry. 6081 if (always && !pa.mPref.sameSet(query)) { 6082 Slog.i(TAG, "Result set changed, dropping preferred activity for " 6083 + intent + " type " + resolvedType); 6084 if (DEBUG_PREFERRED) { 6085 Slog.v(TAG, "Removing preferred activity since set changed " 6086 + pa.mPref.mComponent); 6087 } 6088 pir.removeFilter(pa); 6089 // Re-add the filter as a "last chosen" entry (!always) 6090 PreferredActivity lastChosen = new PreferredActivity( 6091 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 6092 pir.addFilter(lastChosen); 6093 changed = true; 6094 return null; 6095 } 6096 6097 // Yay! Either the set matched or we're looking for the last chosen 6098 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 6099 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 6100 return ri; 6101 } 6102 } 6103 } finally { 6104 if (changed) { 6105 if (DEBUG_PREFERRED) { 6106 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 6107 } 6108 scheduleWritePackageRestrictionsLocked(userId); 6109 } 6110 } 6111 } 6112 } 6113 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 6114 return null; 6115 } 6116 6117 /* 6118 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 6119 */ 6120 @Override 6121 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 6122 int targetUserId) { 6123 mContext.enforceCallingOrSelfPermission( 6124 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 6125 List<CrossProfileIntentFilter> matches = 6126 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 6127 if (matches != null) { 6128 int size = matches.size(); 6129 for (int i = 0; i < size; i++) { 6130 if (matches.get(i).getTargetUserId() == targetUserId) return true; 6131 } 6132 } 6133 if (hasWebURI(intent)) { 6134 // cross-profile app linking works only towards the parent. 6135 final UserInfo parent = getProfileParent(sourceUserId); 6136 synchronized(mPackages) { 6137 int flags = updateFlagsForResolve(0, parent.id, intent, false); 6138 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 6139 intent, resolvedType, flags, sourceUserId, parent.id); 6140 return xpDomainInfo != null; 6141 } 6142 } 6143 return false; 6144 } 6145 6146 private UserInfo getProfileParent(int userId) { 6147 final long identity = Binder.clearCallingIdentity(); 6148 try { 6149 return sUserManager.getProfileParent(userId); 6150 } finally { 6151 Binder.restoreCallingIdentity(identity); 6152 } 6153 } 6154 6155 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 6156 String resolvedType, int userId) { 6157 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 6158 if (resolver != null) { 6159 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId); 6160 } 6161 return null; 6162 } 6163 6164 @Override 6165 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 6166 String resolvedType, int flags, int userId) { 6167 try { 6168 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 6169 6170 return new ParceledListSlice<>( 6171 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 6172 } finally { 6173 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6174 } 6175 } 6176 6177 /** 6178 * Returns the package name of the calling Uid if it's an instant app. If it isn't 6179 * instant, returns {@code null}. 6180 */ 6181 private String getInstantAppPackageName(int callingUid) { 6182 // If the caller is an isolated app use the owner's uid for the lookup. 6183 if (Process.isIsolated(callingUid)) { 6184 callingUid = mIsolatedOwners.get(callingUid); 6185 } 6186 final int appId = UserHandle.getAppId(callingUid); 6187 synchronized (mPackages) { 6188 final Object obj = mSettings.getUserIdLPr(appId); 6189 if (obj instanceof PackageSetting) { 6190 final PackageSetting ps = (PackageSetting) obj; 6191 final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid)); 6192 return isInstantApp ? ps.pkg.packageName : null; 6193 } 6194 } 6195 return null; 6196 } 6197 6198 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 6199 String resolvedType, int flags, int userId) { 6200 return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false); 6201 } 6202 6203 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 6204 String resolvedType, int flags, int userId, boolean includeInstantApp) { 6205 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6206 final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid()); 6207 flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp); 6208 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6209 false /* requireFullPermission */, false /* checkShell */, 6210 "query intent activities"); 6211 ComponentName comp = intent.getComponent(); 6212 if (comp == null) { 6213 if (intent.getSelector() != null) { 6214 intent = intent.getSelector(); 6215 comp = intent.getComponent(); 6216 } 6217 } 6218 6219 if (comp != null) { 6220 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6221 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 6222 if (ai != null) { 6223 // When specifying an explicit component, we prevent the activity from being 6224 // used when either 1) the calling package is normal and the activity is within 6225 // an ephemeral application or 2) the calling package is ephemeral and the 6226 // activity is not visible to ephemeral applications. 6227 final boolean matchInstantApp = 6228 (flags & PackageManager.MATCH_INSTANT) != 0; 6229 final boolean matchVisibleToInstantAppOnly = 6230 (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; 6231 final boolean isCallerInstantApp = 6232 instantAppPkgName != null; 6233 final boolean isTargetSameInstantApp = 6234 comp.getPackageName().equals(instantAppPkgName); 6235 final boolean isTargetInstantApp = 6236 (ai.applicationInfo.privateFlags 6237 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0; 6238 final boolean isTargetHiddenFromInstantApp = 6239 (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0; 6240 final boolean blockResolution = 6241 !isTargetSameInstantApp 6242 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp) 6243 || (matchVisibleToInstantAppOnly && isCallerInstantApp 6244 && isTargetHiddenFromInstantApp)); 6245 if (!blockResolution) { 6246 final ResolveInfo ri = new ResolveInfo(); 6247 ri.activityInfo = ai; 6248 list.add(ri); 6249 } 6250 } 6251 return applyPostResolutionFilter(list, instantAppPkgName); 6252 } 6253 6254 // reader 6255 boolean sortResult = false; 6256 boolean addEphemeral = false; 6257 List<ResolveInfo> result; 6258 final String pkgName = intent.getPackage(); 6259 final boolean ephemeralDisabled = isEphemeralDisabled(); 6260 synchronized (mPackages) { 6261 if (pkgName == null) { 6262 List<CrossProfileIntentFilter> matchingFilters = 6263 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 6264 // Check for results that need to skip the current profile. 6265 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 6266 resolvedType, flags, userId); 6267 if (xpResolveInfo != null) { 6268 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); 6269 xpResult.add(xpResolveInfo); 6270 return applyPostResolutionFilter( 6271 filterIfNotSystemUser(xpResult, userId), instantAppPkgName); 6272 } 6273 6274 // Check for results in the current profile. 6275 result = filterIfNotSystemUser(mActivities.queryIntent( 6276 intent, resolvedType, flags, userId), userId); 6277 addEphemeral = !ephemeralDisabled 6278 && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); 6279 6280 // Check for cross profile results. 6281 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 6282 xpResolveInfo = queryCrossProfileIntents( 6283 matchingFilters, intent, resolvedType, flags, userId, 6284 hasNonNegativePriorityResult); 6285 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 6286 boolean isVisibleToUser = filterIfNotSystemUser( 6287 Collections.singletonList(xpResolveInfo), userId).size() > 0; 6288 if (isVisibleToUser) { 6289 result.add(xpResolveInfo); 6290 sortResult = true; 6291 } 6292 } 6293 if (hasWebURI(intent)) { 6294 CrossProfileDomainInfo xpDomainInfo = null; 6295 final UserInfo parent = getProfileParent(userId); 6296 if (parent != null) { 6297 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 6298 flags, userId, parent.id); 6299 } 6300 if (xpDomainInfo != null) { 6301 if (xpResolveInfo != null) { 6302 // If we didn't remove it, the cross-profile ResolveInfo would be twice 6303 // in the result. 6304 result.remove(xpResolveInfo); 6305 } 6306 if (result.size() == 0 && !addEphemeral) { 6307 // No result in current profile, but found candidate in parent user. 6308 // And we are not going to add emphemeral app, so we can return the 6309 // result straight away. 6310 result.add(xpDomainInfo.resolveInfo); 6311 return applyPostResolutionFilter(result, instantAppPkgName); 6312 } 6313 } else if (result.size() <= 1 && !addEphemeral) { 6314 // No result in parent user and <= 1 result in current profile, and we 6315 // are not going to add emphemeral app, so we can return the result without 6316 // further processing. 6317 return applyPostResolutionFilter(result, instantAppPkgName); 6318 } 6319 // We have more than one candidate (combining results from current and parent 6320 // profile), so we need filtering and sorting. 6321 result = filterCandidatesWithDomainPreferredActivitiesLPr( 6322 intent, flags, result, xpDomainInfo, userId); 6323 sortResult = true; 6324 } 6325 } else { 6326 final PackageParser.Package pkg = mPackages.get(pkgName); 6327 if (pkg != null) { 6328 return applyPostResolutionFilter(filterIfNotSystemUser( 6329 mActivities.queryIntentForPackage( 6330 intent, resolvedType, flags, pkg.activities, userId), 6331 userId), instantAppPkgName); 6332 } else { 6333 // the caller wants to resolve for a particular package; however, there 6334 // were no installed results, so, try to find an ephemeral result 6335 addEphemeral = !ephemeralDisabled 6336 && isEphemeralAllowed( 6337 intent, null /*result*/, userId, true /*skipPackageCheck*/); 6338 result = new ArrayList<ResolveInfo>(); 6339 } 6340 } 6341 } 6342 if (addEphemeral) { 6343 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 6344 final InstantAppRequest requestObject = new InstantAppRequest( 6345 null /*responseObj*/, intent /*origIntent*/, resolvedType, 6346 null /*callingPackage*/, userId); 6347 final AuxiliaryResolveInfo auxiliaryResponse = 6348 InstantAppResolver.doInstantAppResolutionPhaseOne( 6349 mContext, mInstantAppResolverConnection, requestObject); 6350 if (auxiliaryResponse != null) { 6351 if (DEBUG_EPHEMERAL) { 6352 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 6353 } 6354 final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo); 6355 ephemeralInstaller.activityInfo = new ActivityInfo(mInstantAppInstallerActivity); 6356 ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token; 6357 ephemeralInstaller.auxiliaryInfo = auxiliaryResponse; 6358 // make sure this resolver is the default 6359 ephemeralInstaller.isDefault = true; 6360 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 6361 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 6362 // add a non-generic filter 6363 ephemeralInstaller.filter = new IntentFilter(intent.getAction()); 6364 ephemeralInstaller.filter.addDataPath( 6365 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL); 6366 ephemeralInstaller.instantAppAvailable = true; 6367 result.add(ephemeralInstaller); 6368 } 6369 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6370 } 6371 if (sortResult) { 6372 Collections.sort(result, mResolvePrioritySorter); 6373 } 6374 return applyPostResolutionFilter(result, instantAppPkgName); 6375 } 6376 6377 private static class CrossProfileDomainInfo { 6378 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 6379 ResolveInfo resolveInfo; 6380 /* Best domain verification status of the activities found in the other profile */ 6381 int bestDomainVerificationStatus; 6382 } 6383 6384 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 6385 String resolvedType, int flags, int sourceUserId, int parentUserId) { 6386 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 6387 sourceUserId)) { 6388 return null; 6389 } 6390 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 6391 resolvedType, flags, parentUserId); 6392 6393 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 6394 return null; 6395 } 6396 CrossProfileDomainInfo result = null; 6397 int size = resultTargetUser.size(); 6398 for (int i = 0; i < size; i++) { 6399 ResolveInfo riTargetUser = resultTargetUser.get(i); 6400 // Intent filter verification is only for filters that specify a host. So don't return 6401 // those that handle all web uris. 6402 if (riTargetUser.handleAllWebDataURI) { 6403 continue; 6404 } 6405 String packageName = riTargetUser.activityInfo.packageName; 6406 PackageSetting ps = mSettings.mPackages.get(packageName); 6407 if (ps == null) { 6408 continue; 6409 } 6410 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 6411 int status = (int)(verificationState >> 32); 6412 if (result == null) { 6413 result = new CrossProfileDomainInfo(); 6414 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 6415 sourceUserId, parentUserId); 6416 result.bestDomainVerificationStatus = status; 6417 } else { 6418 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 6419 result.bestDomainVerificationStatus); 6420 } 6421 } 6422 // Don't consider matches with status NEVER across profiles. 6423 if (result != null && result.bestDomainVerificationStatus 6424 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6425 return null; 6426 } 6427 return result; 6428 } 6429 6430 /** 6431 * Verification statuses are ordered from the worse to the best, except for 6432 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 6433 */ 6434 private int bestDomainVerificationStatus(int status1, int status2) { 6435 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6436 return status2; 6437 } 6438 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6439 return status1; 6440 } 6441 return (int) MathUtils.max(status1, status2); 6442 } 6443 6444 private boolean isUserEnabled(int userId) { 6445 long callingId = Binder.clearCallingIdentity(); 6446 try { 6447 UserInfo userInfo = sUserManager.getUserInfo(userId); 6448 return userInfo != null && userInfo.isEnabled(); 6449 } finally { 6450 Binder.restoreCallingIdentity(callingId); 6451 } 6452 } 6453 6454 /** 6455 * Filter out activities with systemUserOnly flag set, when current user is not System. 6456 * 6457 * @return filtered list 6458 */ 6459 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 6460 if (userId == UserHandle.USER_SYSTEM) { 6461 return resolveInfos; 6462 } 6463 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 6464 ResolveInfo info = resolveInfos.get(i); 6465 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 6466 resolveInfos.remove(i); 6467 } 6468 } 6469 return resolveInfos; 6470 } 6471 6472 /** 6473 * Filters out ephemeral activities. 6474 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the 6475 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned. 6476 * 6477 * @param resolveInfos The pre-filtered list of resolved activities 6478 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering 6479 * is performed. 6480 * @return A filtered list of resolved activities. 6481 */ 6482 private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos, 6483 String ephemeralPkgName) { 6484 // TODO: When adding on-demand split support for non-instant apps, remove this check 6485 // and always apply post filtering 6486 if (ephemeralPkgName == null) { 6487 return resolveInfos; 6488 } 6489 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 6490 final ResolveInfo info = resolveInfos.get(i); 6491 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp(); 6492 // allow activities that are defined in the provided package 6493 if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) { 6494 if (info.activityInfo.splitName != null 6495 && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames, 6496 info.activityInfo.splitName)) { 6497 // requested activity is defined in a split that hasn't been installed yet. 6498 // add the installer to the resolve list 6499 if (DEBUG_EPHEMERAL) { 6500 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 6501 } 6502 final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo); 6503 installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo( 6504 info.activityInfo.packageName, info.activityInfo.splitName, 6505 info.activityInfo.applicationInfo.versionCode); 6506 // make sure this resolver is the default 6507 installerInfo.isDefault = true; 6508 installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 6509 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 6510 // add a non-generic filter 6511 installerInfo.filter = new IntentFilter(); 6512 // load resources from the correct package 6513 installerInfo.resolvePackageName = info.getComponentInfo().packageName; 6514 resolveInfos.set(i, installerInfo); 6515 } 6516 continue; 6517 } 6518 // allow activities that have been explicitly exposed to ephemeral apps 6519 if (!isEphemeralApp 6520 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) { 6521 continue; 6522 } 6523 resolveInfos.remove(i); 6524 } 6525 return resolveInfos; 6526 } 6527 6528 /** 6529 * @param resolveInfos list of resolve infos in descending priority order 6530 * @return if the list contains a resolve info with non-negative priority 6531 */ 6532 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 6533 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 6534 } 6535 6536 private static boolean hasWebURI(Intent intent) { 6537 if (intent.getData() == null) { 6538 return false; 6539 } 6540 final String scheme = intent.getScheme(); 6541 if (TextUtils.isEmpty(scheme)) { 6542 return false; 6543 } 6544 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 6545 } 6546 6547 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 6548 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 6549 int userId) { 6550 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 6551 6552 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 6553 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 6554 candidates.size()); 6555 } 6556 6557 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 6558 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 6559 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 6560 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 6561 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 6562 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 6563 6564 synchronized (mPackages) { 6565 final int count = candidates.size(); 6566 // First, try to use linked apps. Partition the candidates into four lists: 6567 // one for the final results, one for the "do not use ever", one for "undefined status" 6568 // and finally one for "browser app type". 6569 for (int n=0; n<count; n++) { 6570 ResolveInfo info = candidates.get(n); 6571 String packageName = info.activityInfo.packageName; 6572 PackageSetting ps = mSettings.mPackages.get(packageName); 6573 if (ps != null) { 6574 // Add to the special match all list (Browser use case) 6575 if (info.handleAllWebDataURI) { 6576 matchAllList.add(info); 6577 continue; 6578 } 6579 // Try to get the status from User settings first 6580 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 6581 int status = (int)(packedStatus >> 32); 6582 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 6583 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 6584 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6585 Slog.i(TAG, " + always: " + info.activityInfo.packageName 6586 + " : linkgen=" + linkGeneration); 6587 } 6588 // Use link-enabled generation as preferredOrder, i.e. 6589 // prefer newly-enabled over earlier-enabled. 6590 info.preferredOrder = linkGeneration; 6591 alwaysList.add(info); 6592 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 6593 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6594 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 6595 } 6596 neverList.add(info); 6597 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 6598 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6599 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 6600 } 6601 alwaysAskList.add(info); 6602 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 6603 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 6604 if (DEBUG_DOMAIN_VERIFICATION || debug) { 6605 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 6606 } 6607 undefinedList.add(info); 6608 } 6609 } 6610 } 6611 6612 // We'll want to include browser possibilities in a few cases 6613 boolean includeBrowser = false; 6614 6615 // First try to add the "always" resolution(s) for the current user, if any 6616 if (alwaysList.size() > 0) { 6617 result.addAll(alwaysList); 6618 } else { 6619 // Add all undefined apps as we want them to appear in the disambiguation dialog. 6620 result.addAll(undefinedList); 6621 // Maybe add one for the other profile. 6622 if (xpDomainInfo != null && ( 6623 xpDomainInfo.bestDomainVerificationStatus 6624 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 6625 result.add(xpDomainInfo.resolveInfo); 6626 } 6627 includeBrowser = true; 6628 } 6629 6630 // The presence of any 'always ask' alternatives means we'll also offer browsers. 6631 // If there were 'always' entries their preferred order has been set, so we also 6632 // back that off to make the alternatives equivalent 6633 if (alwaysAskList.size() > 0) { 6634 for (ResolveInfo i : result) { 6635 i.preferredOrder = 0; 6636 } 6637 result.addAll(alwaysAskList); 6638 includeBrowser = true; 6639 } 6640 6641 if (includeBrowser) { 6642 // Also add browsers (all of them or only the default one) 6643 if (DEBUG_DOMAIN_VERIFICATION) { 6644 Slog.v(TAG, " ...including browsers in candidate set"); 6645 } 6646 if ((matchFlags & MATCH_ALL) != 0) { 6647 result.addAll(matchAllList); 6648 } else { 6649 // Browser/generic handling case. If there's a default browser, go straight 6650 // to that (but only if there is no other higher-priority match). 6651 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 6652 int maxMatchPrio = 0; 6653 ResolveInfo defaultBrowserMatch = null; 6654 final int numCandidates = matchAllList.size(); 6655 for (int n = 0; n < numCandidates; n++) { 6656 ResolveInfo info = matchAllList.get(n); 6657 // track the highest overall match priority... 6658 if (info.priority > maxMatchPrio) { 6659 maxMatchPrio = info.priority; 6660 } 6661 // ...and the highest-priority default browser match 6662 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 6663 if (defaultBrowserMatch == null 6664 || (defaultBrowserMatch.priority < info.priority)) { 6665 if (debug) { 6666 Slog.v(TAG, "Considering default browser match " + info); 6667 } 6668 defaultBrowserMatch = info; 6669 } 6670 } 6671 } 6672 if (defaultBrowserMatch != null 6673 && defaultBrowserMatch.priority >= maxMatchPrio 6674 && !TextUtils.isEmpty(defaultBrowserPackageName)) 6675 { 6676 if (debug) { 6677 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 6678 } 6679 result.add(defaultBrowserMatch); 6680 } else { 6681 result.addAll(matchAllList); 6682 } 6683 } 6684 6685 // If there is nothing selected, add all candidates and remove the ones that the user 6686 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 6687 if (result.size() == 0) { 6688 result.addAll(candidates); 6689 result.removeAll(neverList); 6690 } 6691 } 6692 } 6693 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 6694 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 6695 result.size()); 6696 for (ResolveInfo info : result) { 6697 Slog.v(TAG, " + " + info.activityInfo); 6698 } 6699 } 6700 return result; 6701 } 6702 6703 // Returns a packed value as a long: 6704 // 6705 // high 'int'-sized word: link status: undefined/ask/never/always. 6706 // low 'int'-sized word: relative priority among 'always' results. 6707 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 6708 long result = ps.getDomainVerificationStatusForUser(userId); 6709 // if none available, get the master status 6710 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 6711 if (ps.getIntentFilterVerificationInfo() != null) { 6712 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 6713 } 6714 } 6715 return result; 6716 } 6717 6718 private ResolveInfo querySkipCurrentProfileIntents( 6719 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6720 int flags, int sourceUserId) { 6721 if (matchingFilters != null) { 6722 int size = matchingFilters.size(); 6723 for (int i = 0; i < size; i ++) { 6724 CrossProfileIntentFilter filter = matchingFilters.get(i); 6725 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 6726 // Checking if there are activities in the target user that can handle the 6727 // intent. 6728 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6729 resolvedType, flags, sourceUserId); 6730 if (resolveInfo != null) { 6731 return resolveInfo; 6732 } 6733 } 6734 } 6735 } 6736 return null; 6737 } 6738 6739 // Return matching ResolveInfo in target user if any. 6740 private ResolveInfo queryCrossProfileIntents( 6741 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6742 int flags, int sourceUserId, boolean matchInCurrentProfile) { 6743 if (matchingFilters != null) { 6744 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 6745 // match the same intent. For performance reasons, it is better not to 6746 // run queryIntent twice for the same userId 6747 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 6748 int size = matchingFilters.size(); 6749 for (int i = 0; i < size; i++) { 6750 CrossProfileIntentFilter filter = matchingFilters.get(i); 6751 int targetUserId = filter.getTargetUserId(); 6752 boolean skipCurrentProfile = 6753 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 6754 boolean skipCurrentProfileIfNoMatchFound = 6755 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 6756 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 6757 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 6758 // Checking if there are activities in the target user that can handle the 6759 // intent. 6760 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6761 resolvedType, flags, sourceUserId); 6762 if (resolveInfo != null) return resolveInfo; 6763 alreadyTriedUserIds.put(targetUserId, true); 6764 } 6765 } 6766 } 6767 return null; 6768 } 6769 6770 /** 6771 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 6772 * will forward the intent to the filter's target user. 6773 * Otherwise, returns null. 6774 */ 6775 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 6776 String resolvedType, int flags, int sourceUserId) { 6777 int targetUserId = filter.getTargetUserId(); 6778 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 6779 resolvedType, flags, targetUserId); 6780 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 6781 // If all the matches in the target profile are suspended, return null. 6782 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 6783 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 6784 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 6785 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 6786 targetUserId); 6787 } 6788 } 6789 } 6790 return null; 6791 } 6792 6793 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 6794 int sourceUserId, int targetUserId) { 6795 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 6796 long ident = Binder.clearCallingIdentity(); 6797 boolean targetIsProfile; 6798 try { 6799 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 6800 } finally { 6801 Binder.restoreCallingIdentity(ident); 6802 } 6803 String className; 6804 if (targetIsProfile) { 6805 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 6806 } else { 6807 className = FORWARD_INTENT_TO_PARENT; 6808 } 6809 ComponentName forwardingActivityComponentName = new ComponentName( 6810 mAndroidApplication.packageName, className); 6811 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 6812 sourceUserId); 6813 if (!targetIsProfile) { 6814 forwardingActivityInfo.showUserIcon = targetUserId; 6815 forwardingResolveInfo.noResourceId = true; 6816 } 6817 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 6818 forwardingResolveInfo.priority = 0; 6819 forwardingResolveInfo.preferredOrder = 0; 6820 forwardingResolveInfo.match = 0; 6821 forwardingResolveInfo.isDefault = true; 6822 forwardingResolveInfo.filter = filter; 6823 forwardingResolveInfo.targetUserId = targetUserId; 6824 return forwardingResolveInfo; 6825 } 6826 6827 @Override 6828 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 6829 Intent[] specifics, String[] specificTypes, Intent intent, 6830 String resolvedType, int flags, int userId) { 6831 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 6832 specificTypes, intent, resolvedType, flags, userId)); 6833 } 6834 6835 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 6836 Intent[] specifics, String[] specificTypes, Intent intent, 6837 String resolvedType, int flags, int userId) { 6838 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6839 flags = updateFlagsForResolve(flags, userId, intent, false); 6840 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6841 false /* requireFullPermission */, false /* checkShell */, 6842 "query intent activity options"); 6843 final String resultsAction = intent.getAction(); 6844 6845 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 6846 | PackageManager.GET_RESOLVED_FILTER, userId); 6847 6848 if (DEBUG_INTENT_MATCHING) { 6849 Log.v(TAG, "Query " + intent + ": " + results); 6850 } 6851 6852 int specificsPos = 0; 6853 int N; 6854 6855 // todo: note that the algorithm used here is O(N^2). This 6856 // isn't a problem in our current environment, but if we start running 6857 // into situations where we have more than 5 or 10 matches then this 6858 // should probably be changed to something smarter... 6859 6860 // First we go through and resolve each of the specific items 6861 // that were supplied, taking care of removing any corresponding 6862 // duplicate items in the generic resolve list. 6863 if (specifics != null) { 6864 for (int i=0; i<specifics.length; i++) { 6865 final Intent sintent = specifics[i]; 6866 if (sintent == null) { 6867 continue; 6868 } 6869 6870 if (DEBUG_INTENT_MATCHING) { 6871 Log.v(TAG, "Specific #" + i + ": " + sintent); 6872 } 6873 6874 String action = sintent.getAction(); 6875 if (resultsAction != null && resultsAction.equals(action)) { 6876 // If this action was explicitly requested, then don't 6877 // remove things that have it. 6878 action = null; 6879 } 6880 6881 ResolveInfo ri = null; 6882 ActivityInfo ai = null; 6883 6884 ComponentName comp = sintent.getComponent(); 6885 if (comp == null) { 6886 ri = resolveIntent( 6887 sintent, 6888 specificTypes != null ? specificTypes[i] : null, 6889 flags, userId); 6890 if (ri == null) { 6891 continue; 6892 } 6893 if (ri == mResolveInfo) { 6894 // ACK! Must do something better with this. 6895 } 6896 ai = ri.activityInfo; 6897 comp = new ComponentName(ai.applicationInfo.packageName, 6898 ai.name); 6899 } else { 6900 ai = getActivityInfo(comp, flags, userId); 6901 if (ai == null) { 6902 continue; 6903 } 6904 } 6905 6906 // Look for any generic query activities that are duplicates 6907 // of this specific one, and remove them from the results. 6908 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 6909 N = results.size(); 6910 int j; 6911 for (j=specificsPos; j<N; j++) { 6912 ResolveInfo sri = results.get(j); 6913 if ((sri.activityInfo.name.equals(comp.getClassName()) 6914 && sri.activityInfo.applicationInfo.packageName.equals( 6915 comp.getPackageName())) 6916 || (action != null && sri.filter.matchAction(action))) { 6917 results.remove(j); 6918 if (DEBUG_INTENT_MATCHING) Log.v( 6919 TAG, "Removing duplicate item from " + j 6920 + " due to specific " + specificsPos); 6921 if (ri == null) { 6922 ri = sri; 6923 } 6924 j--; 6925 N--; 6926 } 6927 } 6928 6929 // Add this specific item to its proper place. 6930 if (ri == null) { 6931 ri = new ResolveInfo(); 6932 ri.activityInfo = ai; 6933 } 6934 results.add(specificsPos, ri); 6935 ri.specificIndex = i; 6936 specificsPos++; 6937 } 6938 } 6939 6940 // Now we go through the remaining generic results and remove any 6941 // duplicate actions that are found here. 6942 N = results.size(); 6943 for (int i=specificsPos; i<N-1; i++) { 6944 final ResolveInfo rii = results.get(i); 6945 if (rii.filter == null) { 6946 continue; 6947 } 6948 6949 // Iterate over all of the actions of this result's intent 6950 // filter... typically this should be just one. 6951 final Iterator<String> it = rii.filter.actionsIterator(); 6952 if (it == null) { 6953 continue; 6954 } 6955 while (it.hasNext()) { 6956 final String action = it.next(); 6957 if (resultsAction != null && resultsAction.equals(action)) { 6958 // If this action was explicitly requested, then don't 6959 // remove things that have it. 6960 continue; 6961 } 6962 for (int j=i+1; j<N; j++) { 6963 final ResolveInfo rij = results.get(j); 6964 if (rij.filter != null && rij.filter.hasAction(action)) { 6965 results.remove(j); 6966 if (DEBUG_INTENT_MATCHING) Log.v( 6967 TAG, "Removing duplicate item from " + j 6968 + " due to action " + action + " at " + i); 6969 j--; 6970 N--; 6971 } 6972 } 6973 } 6974 6975 // If the caller didn't request filter information, drop it now 6976 // so we don't have to marshall/unmarshall it. 6977 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6978 rii.filter = null; 6979 } 6980 } 6981 6982 // Filter out the caller activity if so requested. 6983 if (caller != null) { 6984 N = results.size(); 6985 for (int i=0; i<N; i++) { 6986 ActivityInfo ainfo = results.get(i).activityInfo; 6987 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 6988 && caller.getClassName().equals(ainfo.name)) { 6989 results.remove(i); 6990 break; 6991 } 6992 } 6993 } 6994 6995 // If the caller didn't request filter information, 6996 // drop them now so we don't have to 6997 // marshall/unmarshall it. 6998 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6999 N = results.size(); 7000 for (int i=0; i<N; i++) { 7001 results.get(i).filter = null; 7002 } 7003 } 7004 7005 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 7006 return results; 7007 } 7008 7009 @Override 7010 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 7011 String resolvedType, int flags, int userId) { 7012 return new ParceledListSlice<>( 7013 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 7014 } 7015 7016 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 7017 String resolvedType, int flags, int userId) { 7018 if (!sUserManager.exists(userId)) return Collections.emptyList(); 7019 flags = updateFlagsForResolve(flags, userId, intent, false); 7020 ComponentName comp = intent.getComponent(); 7021 if (comp == null) { 7022 if (intent.getSelector() != null) { 7023 intent = intent.getSelector(); 7024 comp = intent.getComponent(); 7025 } 7026 } 7027 if (comp != null) { 7028 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 7029 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 7030 if (ai != null) { 7031 ResolveInfo ri = new ResolveInfo(); 7032 ri.activityInfo = ai; 7033 list.add(ri); 7034 } 7035 return list; 7036 } 7037 7038 // reader 7039 synchronized (mPackages) { 7040 String pkgName = intent.getPackage(); 7041 if (pkgName == null) { 7042 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 7043 } 7044 final PackageParser.Package pkg = mPackages.get(pkgName); 7045 if (pkg != null) { 7046 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 7047 userId); 7048 } 7049 return Collections.emptyList(); 7050 } 7051 } 7052 7053 @Override 7054 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 7055 if (!sUserManager.exists(userId)) return null; 7056 flags = updateFlagsForResolve(flags, userId, intent, false); 7057 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 7058 if (query != null) { 7059 if (query.size() >= 1) { 7060 // If there is more than one service with the same priority, 7061 // just arbitrarily pick the first one. 7062 return query.get(0); 7063 } 7064 } 7065 return null; 7066 } 7067 7068 @Override 7069 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 7070 String resolvedType, int flags, int userId) { 7071 return new ParceledListSlice<>( 7072 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 7073 } 7074 7075 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 7076 String resolvedType, int flags, int userId) { 7077 if (!sUserManager.exists(userId)) return Collections.emptyList(); 7078 flags = updateFlagsForResolve(flags, userId, intent, false); 7079 ComponentName comp = intent.getComponent(); 7080 if (comp == null) { 7081 if (intent.getSelector() != null) { 7082 intent = intent.getSelector(); 7083 comp = intent.getComponent(); 7084 } 7085 } 7086 if (comp != null) { 7087 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 7088 final ServiceInfo si = getServiceInfo(comp, flags, userId); 7089 if (si != null) { 7090 final ResolveInfo ri = new ResolveInfo(); 7091 ri.serviceInfo = si; 7092 list.add(ri); 7093 } 7094 return list; 7095 } 7096 7097 // reader 7098 synchronized (mPackages) { 7099 String pkgName = intent.getPackage(); 7100 if (pkgName == null) { 7101 return mServices.queryIntent(intent, resolvedType, flags, userId); 7102 } 7103 final PackageParser.Package pkg = mPackages.get(pkgName); 7104 if (pkg != null) { 7105 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 7106 userId); 7107 } 7108 return Collections.emptyList(); 7109 } 7110 } 7111 7112 @Override 7113 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 7114 String resolvedType, int flags, int userId) { 7115 return new ParceledListSlice<>( 7116 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 7117 } 7118 7119 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 7120 Intent intent, String resolvedType, int flags, int userId) { 7121 if (!sUserManager.exists(userId)) return Collections.emptyList(); 7122 flags = updateFlagsForResolve(flags, userId, intent, false); 7123 ComponentName comp = intent.getComponent(); 7124 if (comp == null) { 7125 if (intent.getSelector() != null) { 7126 intent = intent.getSelector(); 7127 comp = intent.getComponent(); 7128 } 7129 } 7130 if (comp != null) { 7131 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 7132 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 7133 if (pi != null) { 7134 final ResolveInfo ri = new ResolveInfo(); 7135 ri.providerInfo = pi; 7136 list.add(ri); 7137 } 7138 return list; 7139 } 7140 7141 // reader 7142 synchronized (mPackages) { 7143 String pkgName = intent.getPackage(); 7144 if (pkgName == null) { 7145 return mProviders.queryIntent(intent, resolvedType, flags, userId); 7146 } 7147 final PackageParser.Package pkg = mPackages.get(pkgName); 7148 if (pkg != null) { 7149 return mProviders.queryIntentForPackage( 7150 intent, resolvedType, flags, pkg.providers, userId); 7151 } 7152 return Collections.emptyList(); 7153 } 7154 } 7155 7156 @Override 7157 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 7158 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7159 flags = updateFlagsForPackage(flags, userId, null); 7160 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 7161 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7162 true /* requireFullPermission */, false /* checkShell */, 7163 "get installed packages"); 7164 7165 // writer 7166 synchronized (mPackages) { 7167 ArrayList<PackageInfo> list; 7168 if (listUninstalled) { 7169 list = new ArrayList<>(mSettings.mPackages.size()); 7170 for (PackageSetting ps : mSettings.mPackages.values()) { 7171 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7172 continue; 7173 } 7174 final PackageInfo pi = generatePackageInfo(ps, flags, userId); 7175 if (pi != null) { 7176 list.add(pi); 7177 } 7178 } 7179 } else { 7180 list = new ArrayList<>(mPackages.size()); 7181 for (PackageParser.Package p : mPackages.values()) { 7182 if (filterSharedLibPackageLPr((PackageSetting) p.mExtras, 7183 Binder.getCallingUid(), userId)) { 7184 continue; 7185 } 7186 final PackageInfo pi = generatePackageInfo((PackageSetting) 7187 p.mExtras, flags, userId); 7188 if (pi != null) { 7189 list.add(pi); 7190 } 7191 } 7192 } 7193 7194 return new ParceledListSlice<>(list); 7195 } 7196 } 7197 7198 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 7199 String[] permissions, boolean[] tmp, int flags, int userId) { 7200 int numMatch = 0; 7201 final PermissionsState permissionsState = ps.getPermissionsState(); 7202 for (int i=0; i<permissions.length; i++) { 7203 final String permission = permissions[i]; 7204 if (permissionsState.hasPermission(permission, userId)) { 7205 tmp[i] = true; 7206 numMatch++; 7207 } else { 7208 tmp[i] = false; 7209 } 7210 } 7211 if (numMatch == 0) { 7212 return; 7213 } 7214 final PackageInfo pi = generatePackageInfo(ps, flags, userId); 7215 7216 // The above might return null in cases of uninstalled apps or install-state 7217 // skew across users/profiles. 7218 if (pi != null) { 7219 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 7220 if (numMatch == permissions.length) { 7221 pi.requestedPermissions = permissions; 7222 } else { 7223 pi.requestedPermissions = new String[numMatch]; 7224 numMatch = 0; 7225 for (int i=0; i<permissions.length; i++) { 7226 if (tmp[i]) { 7227 pi.requestedPermissions[numMatch] = permissions[i]; 7228 numMatch++; 7229 } 7230 } 7231 } 7232 } 7233 list.add(pi); 7234 } 7235 } 7236 7237 @Override 7238 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 7239 String[] permissions, int flags, int userId) { 7240 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7241 flags = updateFlagsForPackage(flags, userId, permissions); 7242 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7243 true /* requireFullPermission */, false /* checkShell */, 7244 "get packages holding permissions"); 7245 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 7246 7247 // writer 7248 synchronized (mPackages) { 7249 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 7250 boolean[] tmpBools = new boolean[permissions.length]; 7251 if (listUninstalled) { 7252 for (PackageSetting ps : mSettings.mPackages.values()) { 7253 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 7254 userId); 7255 } 7256 } else { 7257 for (PackageParser.Package pkg : mPackages.values()) { 7258 PackageSetting ps = (PackageSetting)pkg.mExtras; 7259 if (ps != null) { 7260 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 7261 userId); 7262 } 7263 } 7264 } 7265 7266 return new ParceledListSlice<PackageInfo>(list); 7267 } 7268 } 7269 7270 @Override 7271 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 7272 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7273 flags = updateFlagsForApplication(flags, userId, null); 7274 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 7275 7276 // writer 7277 synchronized (mPackages) { 7278 ArrayList<ApplicationInfo> list; 7279 if (listUninstalled) { 7280 list = new ArrayList<>(mSettings.mPackages.size()); 7281 for (PackageSetting ps : mSettings.mPackages.values()) { 7282 ApplicationInfo ai; 7283 int effectiveFlags = flags; 7284 if (ps.isSystem()) { 7285 effectiveFlags |= PackageManager.MATCH_ANY_USER; 7286 } 7287 if (ps.pkg != null) { 7288 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7289 continue; 7290 } 7291 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags, 7292 ps.readUserState(userId), userId); 7293 if (ai != null) { 7294 rebaseEnabledOverlays(ai, userId); 7295 ai.packageName = resolveExternalPackageNameLPr(ps.pkg); 7296 } 7297 } else { 7298 // Shared lib filtering done in generateApplicationInfoFromSettingsLPw 7299 // and already converts to externally visible package name 7300 ai = generateApplicationInfoFromSettingsLPw(ps.name, 7301 Binder.getCallingUid(), effectiveFlags, userId); 7302 } 7303 if (ai != null) { 7304 list.add(ai); 7305 } 7306 } 7307 } else { 7308 list = new ArrayList<>(mPackages.size()); 7309 for (PackageParser.Package p : mPackages.values()) { 7310 if (p.mExtras != null) { 7311 PackageSetting ps = (PackageSetting) p.mExtras; 7312 if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) { 7313 continue; 7314 } 7315 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 7316 ps.readUserState(userId), userId); 7317 if (ai != null) { 7318 rebaseEnabledOverlays(ai, userId); 7319 ai.packageName = resolveExternalPackageNameLPr(p); 7320 list.add(ai); 7321 } 7322 } 7323 } 7324 } 7325 7326 return new ParceledListSlice<>(list); 7327 } 7328 } 7329 7330 @Override 7331 public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) { 7332 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7333 return null; 7334 } 7335 7336 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, 7337 "getEphemeralApplications"); 7338 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7339 true /* requireFullPermission */, false /* checkShell */, 7340 "getEphemeralApplications"); 7341 synchronized (mPackages) { 7342 List<InstantAppInfo> instantApps = mInstantAppRegistry 7343 .getInstantAppsLPr(userId); 7344 if (instantApps != null) { 7345 return new ParceledListSlice<>(instantApps); 7346 } 7347 } 7348 return null; 7349 } 7350 7351 @Override 7352 public boolean isInstantApp(String packageName, int userId) { 7353 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7354 true /* requireFullPermission */, false /* checkShell */, 7355 "isInstantApp"); 7356 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7357 return false; 7358 } 7359 int uid = Binder.getCallingUid(); 7360 if (Process.isIsolated(uid)) { 7361 uid = mIsolatedOwners.get(uid); 7362 } 7363 7364 synchronized (mPackages) { 7365 final PackageSetting ps = mSettings.mPackages.get(packageName); 7366 PackageParser.Package pkg = mPackages.get(packageName); 7367 final boolean returnAllowed = 7368 ps != null 7369 && (isCallerSameApp(packageName, uid) 7370 || mContext.checkCallingOrSelfPermission( 7371 android.Manifest.permission.ACCESS_INSTANT_APPS) 7372 == PERMISSION_GRANTED 7373 || mInstantAppRegistry.isInstantAccessGranted( 7374 userId, UserHandle.getAppId(uid), ps.appId)); 7375 if (returnAllowed) { 7376 return ps.getInstantApp(userId); 7377 } 7378 } 7379 return false; 7380 } 7381 7382 @Override 7383 public byte[] getInstantAppCookie(String packageName, int userId) { 7384 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7385 return null; 7386 } 7387 7388 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7389 true /* requireFullPermission */, false /* checkShell */, 7390 "getInstantAppCookie"); 7391 if (!isCallerSameApp(packageName, Binder.getCallingUid())) { 7392 return null; 7393 } 7394 synchronized (mPackages) { 7395 return mInstantAppRegistry.getInstantAppCookieLPw( 7396 packageName, userId); 7397 } 7398 } 7399 7400 @Override 7401 public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) { 7402 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7403 return true; 7404 } 7405 7406 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7407 true /* requireFullPermission */, true /* checkShell */, 7408 "setInstantAppCookie"); 7409 if (!isCallerSameApp(packageName, Binder.getCallingUid())) { 7410 return false; 7411 } 7412 synchronized (mPackages) { 7413 return mInstantAppRegistry.setInstantAppCookieLPw( 7414 packageName, cookie, userId); 7415 } 7416 } 7417 7418 @Override 7419 public Bitmap getInstantAppIcon(String packageName, int userId) { 7420 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 7421 return null; 7422 } 7423 7424 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, 7425 "getInstantAppIcon"); 7426 7427 enforceCrossUserPermission(Binder.getCallingUid(), userId, 7428 true /* requireFullPermission */, false /* checkShell */, 7429 "getInstantAppIcon"); 7430 7431 synchronized (mPackages) { 7432 return mInstantAppRegistry.getInstantAppIconLPw( 7433 packageName, userId); 7434 } 7435 } 7436 7437 private boolean isCallerSameApp(String packageName, int uid) { 7438 PackageParser.Package pkg = mPackages.get(packageName); 7439 return pkg != null 7440 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid; 7441 } 7442 7443 @Override 7444 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 7445 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 7446 } 7447 7448 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 7449 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 7450 7451 // reader 7452 synchronized (mPackages) { 7453 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 7454 final int userId = UserHandle.getCallingUserId(); 7455 while (i.hasNext()) { 7456 final PackageParser.Package p = i.next(); 7457 if (p.applicationInfo == null) continue; 7458 7459 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 7460 && !p.applicationInfo.isDirectBootAware(); 7461 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 7462 && p.applicationInfo.isDirectBootAware(); 7463 7464 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 7465 && (!mSafeMode || isSystemApp(p)) 7466 && (matchesUnaware || matchesAware)) { 7467 PackageSetting ps = mSettings.mPackages.get(p.packageName); 7468 if (ps != null) { 7469 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 7470 ps.readUserState(userId), userId); 7471 if (ai != null) { 7472 rebaseEnabledOverlays(ai, userId); 7473 finalList.add(ai); 7474 } 7475 } 7476 } 7477 } 7478 } 7479 7480 return finalList; 7481 } 7482 7483 @Override 7484 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 7485 if (!sUserManager.exists(userId)) return null; 7486 flags = updateFlagsForComponent(flags, userId, name); 7487 // reader 7488 synchronized (mPackages) { 7489 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 7490 PackageSetting ps = provider != null 7491 ? mSettings.mPackages.get(provider.owner.packageName) 7492 : null; 7493 return ps != null 7494 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 7495 ? PackageParser.generateProviderInfo(provider, flags, 7496 ps.readUserState(userId), userId) 7497 : null; 7498 } 7499 } 7500 7501 /** 7502 * @deprecated 7503 */ 7504 @Deprecated 7505 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 7506 // reader 7507 synchronized (mPackages) { 7508 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 7509 .entrySet().iterator(); 7510 final int userId = UserHandle.getCallingUserId(); 7511 while (i.hasNext()) { 7512 Map.Entry<String, PackageParser.Provider> entry = i.next(); 7513 PackageParser.Provider p = entry.getValue(); 7514 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 7515 7516 if (ps != null && p.syncable 7517 && (!mSafeMode || (p.info.applicationInfo.flags 7518 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 7519 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 7520 ps.readUserState(userId), userId); 7521 if (info != null) { 7522 outNames.add(entry.getKey()); 7523 outInfo.add(info); 7524 } 7525 } 7526 } 7527 } 7528 } 7529 7530 @Override 7531 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 7532 int uid, int flags, String metaDataKey) { 7533 final int userId = processName != null ? UserHandle.getUserId(uid) 7534 : UserHandle.getCallingUserId(); 7535 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 7536 flags = updateFlagsForComponent(flags, userId, processName); 7537 7538 ArrayList<ProviderInfo> finalList = null; 7539 // reader 7540 synchronized (mPackages) { 7541 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 7542 while (i.hasNext()) { 7543 final PackageParser.Provider p = i.next(); 7544 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 7545 if (ps != null && p.info.authority != null 7546 && (processName == null 7547 || (p.info.processName.equals(processName) 7548 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 7549 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 7550 7551 // See PM.queryContentProviders()'s javadoc for why we have the metaData 7552 // parameter. 7553 if (metaDataKey != null 7554 && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) { 7555 continue; 7556 } 7557 7558 if (finalList == null) { 7559 finalList = new ArrayList<ProviderInfo>(3); 7560 } 7561 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 7562 ps.readUserState(userId), userId); 7563 if (info != null) { 7564 finalList.add(info); 7565 } 7566 } 7567 } 7568 } 7569 7570 if (finalList != null) { 7571 Collections.sort(finalList, mProviderInitOrderSorter); 7572 return new ParceledListSlice<ProviderInfo>(finalList); 7573 } 7574 7575 return ParceledListSlice.emptyList(); 7576 } 7577 7578 @Override 7579 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 7580 // reader 7581 synchronized (mPackages) { 7582 final PackageParser.Instrumentation i = mInstrumentation.get(name); 7583 return PackageParser.generateInstrumentationInfo(i, flags); 7584 } 7585 } 7586 7587 @Override 7588 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 7589 String targetPackage, int flags) { 7590 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 7591 } 7592 7593 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 7594 int flags) { 7595 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 7596 7597 // reader 7598 synchronized (mPackages) { 7599 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 7600 while (i.hasNext()) { 7601 final PackageParser.Instrumentation p = i.next(); 7602 if (targetPackage == null 7603 || targetPackage.equals(p.info.targetPackage)) { 7604 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 7605 flags); 7606 if (ii != null) { 7607 finalList.add(ii); 7608 } 7609 } 7610 } 7611 } 7612 7613 return finalList; 7614 } 7615 7616 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 7617 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]"); 7618 try { 7619 scanDirLI(dir, parseFlags, scanFlags, currentTime); 7620 } finally { 7621 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7622 } 7623 } 7624 7625 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 7626 final File[] files = dir.listFiles(); 7627 if (ArrayUtils.isEmpty(files)) { 7628 Log.d(TAG, "No files in app dir " + dir); 7629 return; 7630 } 7631 7632 if (DEBUG_PACKAGE_SCANNING) { 7633 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 7634 + " flags=0x" + Integer.toHexString(parseFlags)); 7635 } 7636 ParallelPackageParser parallelPackageParser = new ParallelPackageParser( 7637 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback); 7638 7639 // Submit files for parsing in parallel 7640 int fileCount = 0; 7641 for (File file : files) { 7642 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 7643 && !PackageInstallerService.isStageName(file.getName()); 7644 if (!isPackage) { 7645 // Ignore entries which are not packages 7646 continue; 7647 } 7648 parallelPackageParser.submit(file, parseFlags); 7649 fileCount++; 7650 } 7651 7652 // Process results one by one 7653 for (; fileCount > 0; fileCount--) { 7654 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); 7655 Throwable throwable = parseResult.throwable; 7656 int errorCode = PackageManager.INSTALL_SUCCEEDED; 7657 7658 if (throwable == null) { 7659 // Static shared libraries have synthetic package names 7660 if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) { 7661 renameStaticSharedLibraryPackage(parseResult.pkg); 7662 } 7663 try { 7664 if (errorCode == PackageManager.INSTALL_SUCCEEDED) { 7665 scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags, 7666 currentTime, null); 7667 } 7668 } catch (PackageManagerException e) { 7669 errorCode = e.error; 7670 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage()); 7671 } 7672 } else if (throwable instanceof PackageParser.PackageParserException) { 7673 PackageParser.PackageParserException e = (PackageParser.PackageParserException) 7674 throwable; 7675 errorCode = e.error; 7676 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage()); 7677 } else { 7678 throw new IllegalStateException("Unexpected exception occurred while parsing " 7679 + parseResult.scanFile, throwable); 7680 } 7681 7682 // Delete invalid userdata apps 7683 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 7684 errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) { 7685 logCriticalInfo(Log.WARN, 7686 "Deleting invalid package at " + parseResult.scanFile); 7687 removeCodePathLI(parseResult.scanFile); 7688 } 7689 } 7690 parallelPackageParser.close(); 7691 } 7692 7693 private static File getSettingsProblemFile() { 7694 File dataDir = Environment.getDataDirectory(); 7695 File systemDir = new File(dataDir, "system"); 7696 File fname = new File(systemDir, "uiderrors.txt"); 7697 return fname; 7698 } 7699 7700 static void reportSettingsProblem(int priority, String msg) { 7701 logCriticalInfo(priority, msg); 7702 } 7703 7704 public static void logCriticalInfo(int priority, String msg) { 7705 Slog.println(priority, TAG, msg); 7706 EventLogTags.writePmCriticalInfo(msg); 7707 try { 7708 File fname = getSettingsProblemFile(); 7709 FileOutputStream out = new FileOutputStream(fname, true); 7710 PrintWriter pw = new FastPrintWriter(out); 7711 SimpleDateFormat formatter = new SimpleDateFormat(); 7712 String dateString = formatter.format(new Date(System.currentTimeMillis())); 7713 pw.println(dateString + ": " + msg); 7714 pw.close(); 7715 FileUtils.setPermissions( 7716 fname.toString(), 7717 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 7718 -1, -1); 7719 } catch (java.io.IOException e) { 7720 } 7721 } 7722 7723 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 7724 if (srcFile.isDirectory()) { 7725 final File baseFile = new File(pkg.baseCodePath); 7726 long maxModifiedTime = baseFile.lastModified(); 7727 if (pkg.splitCodePaths != null) { 7728 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 7729 final File splitFile = new File(pkg.splitCodePaths[i]); 7730 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 7731 } 7732 } 7733 return maxModifiedTime; 7734 } 7735 return srcFile.lastModified(); 7736 } 7737 7738 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 7739 final int policyFlags) throws PackageManagerException { 7740 // When upgrading from pre-N MR1, verify the package time stamp using the package 7741 // directory and not the APK file. 7742 final long lastModifiedTime = mIsPreNMR1Upgrade 7743 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile); 7744 if (ps != null 7745 && ps.codePath.equals(srcFile) 7746 && ps.timeStamp == lastModifiedTime 7747 && !isCompatSignatureUpdateNeeded(pkg) 7748 && !isRecoverSignatureUpdateNeeded(pkg)) { 7749 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 7750 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7751 ArraySet<PublicKey> signingKs; 7752 synchronized (mPackages) { 7753 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 7754 } 7755 if (ps.signatures.mSignatures != null 7756 && ps.signatures.mSignatures.length != 0 7757 && signingKs != null) { 7758 // Optimization: reuse the existing cached certificates 7759 // if the package appears to be unchanged. 7760 pkg.mSignatures = ps.signatures.mSignatures; 7761 pkg.mSigningKeys = signingKs; 7762 return; 7763 } 7764 7765 Slog.w(TAG, "PackageSetting for " + ps.name 7766 + " is missing signatures. Collecting certs again to recover them."); 7767 } else { 7768 Slog.i(TAG, srcFile.toString() + " changed; collecting certs"); 7769 } 7770 7771 try { 7772 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 7773 PackageParser.collectCertificates(pkg, policyFlags); 7774 } catch (PackageParserException e) { 7775 throw PackageManagerException.from(e); 7776 } finally { 7777 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7778 } 7779 } 7780 7781 /** 7782 * Traces a package scan. 7783 * @see #scanPackageLI(File, int, int, long, UserHandle) 7784 */ 7785 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 7786 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7787 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 7788 try { 7789 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 7790 } finally { 7791 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7792 } 7793 } 7794 7795 /** 7796 * Scans a package and returns the newly parsed package. 7797 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 7798 */ 7799 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 7800 long currentTime, UserHandle user) throws PackageManagerException { 7801 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 7802 PackageParser pp = new PackageParser(); 7803 pp.setSeparateProcesses(mSeparateProcesses); 7804 pp.setOnlyCoreApps(mOnlyCore); 7805 pp.setDisplayMetrics(mMetrics); 7806 pp.setCallback(mPackageParserCallback); 7807 7808 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 7809 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 7810 } 7811 7812 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 7813 final PackageParser.Package pkg; 7814 try { 7815 pkg = pp.parsePackage(scanFile, parseFlags); 7816 } catch (PackageParserException e) { 7817 throw PackageManagerException.from(e); 7818 } finally { 7819 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7820 } 7821 7822 // Static shared libraries have synthetic package names 7823 if (pkg.applicationInfo.isStaticSharedLibrary()) { 7824 renameStaticSharedLibraryPackage(pkg); 7825 } 7826 7827 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 7828 } 7829 7830 /** 7831 * Scans a package and returns the newly parsed package. 7832 * @throws PackageManagerException on a parse error. 7833 */ 7834 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 7835 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 7836 throws PackageManagerException { 7837 // If the package has children and this is the first dive in the function 7838 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 7839 // packages (parent and children) would be successfully scanned before the 7840 // actual scan since scanning mutates internal state and we want to atomically 7841 // install the package and its children. 7842 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7843 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7844 scanFlags |= SCAN_CHECK_ONLY; 7845 } 7846 } else { 7847 scanFlags &= ~SCAN_CHECK_ONLY; 7848 } 7849 7850 // Scan the parent 7851 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 7852 scanFlags, currentTime, user); 7853 7854 // Scan the children 7855 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7856 for (int i = 0; i < childCount; i++) { 7857 PackageParser.Package childPackage = pkg.childPackages.get(i); 7858 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 7859 currentTime, user); 7860 } 7861 7862 7863 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7864 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 7865 } 7866 7867 return scannedPkg; 7868 } 7869 7870 /** 7871 * Scans a package and returns the newly parsed package. 7872 * @throws PackageManagerException on a parse error. 7873 */ 7874 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 7875 int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 7876 throws PackageManagerException { 7877 PackageSetting ps = null; 7878 PackageSetting updatedPkg; 7879 // reader 7880 synchronized (mPackages) { 7881 // Look to see if we already know about this package. 7882 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName); 7883 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 7884 // This package has been renamed to its original name. Let's 7885 // use that. 7886 ps = mSettings.getPackageLPr(oldName); 7887 } 7888 // If there was no original package, see one for the real package name. 7889 if (ps == null) { 7890 ps = mSettings.getPackageLPr(pkg.packageName); 7891 } 7892 // Check to see if this package could be hiding/updating a system 7893 // package. Must look for it either under the original or real 7894 // package name depending on our state. 7895 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 7896 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 7897 7898 // If this is a package we don't know about on the system partition, we 7899 // may need to remove disabled child packages on the system partition 7900 // or may need to not add child packages if the parent apk is updated 7901 // on the data partition and no longer defines this child package. 7902 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7903 // If this is a parent package for an updated system app and this system 7904 // app got an OTA update which no longer defines some of the child packages 7905 // we have to prune them from the disabled system packages. 7906 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 7907 if (disabledPs != null) { 7908 final int scannedChildCount = (pkg.childPackages != null) 7909 ? pkg.childPackages.size() : 0; 7910 final int disabledChildCount = disabledPs.childPackageNames != null 7911 ? disabledPs.childPackageNames.size() : 0; 7912 for (int i = 0; i < disabledChildCount; i++) { 7913 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 7914 boolean disabledPackageAvailable = false; 7915 for (int j = 0; j < scannedChildCount; j++) { 7916 PackageParser.Package childPkg = pkg.childPackages.get(j); 7917 if (childPkg.packageName.equals(disabledChildPackageName)) { 7918 disabledPackageAvailable = true; 7919 break; 7920 } 7921 } 7922 if (!disabledPackageAvailable) { 7923 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 7924 } 7925 } 7926 } 7927 } 7928 } 7929 7930 boolean updatedPkgBetter = false; 7931 // First check if this is a system package that may involve an update 7932 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7933 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 7934 // it needs to drop FLAG_PRIVILEGED. 7935 if (locationIsPrivileged(scanFile)) { 7936 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7937 } else { 7938 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7939 } 7940 7941 if (ps != null && !ps.codePath.equals(scanFile)) { 7942 // The path has changed from what was last scanned... check the 7943 // version of the new path against what we have stored to determine 7944 // what to do. 7945 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 7946 if (pkg.mVersionCode <= ps.versionCode) { 7947 // The system package has been updated and the code path does not match 7948 // Ignore entry. Skip it. 7949 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 7950 + " ignored: updated version " + ps.versionCode 7951 + " better than this " + pkg.mVersionCode); 7952 if (!updatedPkg.codePath.equals(scanFile)) { 7953 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 7954 + ps.name + " changing from " + updatedPkg.codePathString 7955 + " to " + scanFile); 7956 updatedPkg.codePath = scanFile; 7957 updatedPkg.codePathString = scanFile.toString(); 7958 updatedPkg.resourcePath = scanFile; 7959 updatedPkg.resourcePathString = scanFile.toString(); 7960 } 7961 updatedPkg.pkg = pkg; 7962 updatedPkg.versionCode = pkg.mVersionCode; 7963 7964 // Update the disabled system child packages to point to the package too. 7965 final int childCount = updatedPkg.childPackageNames != null 7966 ? updatedPkg.childPackageNames.size() : 0; 7967 for (int i = 0; i < childCount; i++) { 7968 String childPackageName = updatedPkg.childPackageNames.get(i); 7969 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 7970 childPackageName); 7971 if (updatedChildPkg != null) { 7972 updatedChildPkg.pkg = pkg; 7973 updatedChildPkg.versionCode = pkg.mVersionCode; 7974 } 7975 } 7976 7977 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 7978 + scanFile + " ignored: updated version " + ps.versionCode 7979 + " better than this " + pkg.mVersionCode); 7980 } else { 7981 // The current app on the system partition is better than 7982 // what we have updated to on the data partition; switch 7983 // back to the system partition version. 7984 // At this point, its safely assumed that package installation for 7985 // apps in system partition will go through. If not there won't be a working 7986 // version of the app 7987 // writer 7988 synchronized (mPackages) { 7989 // Just remove the loaded entries from package lists. 7990 mPackages.remove(ps.name); 7991 } 7992 7993 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7994 + " reverting from " + ps.codePathString 7995 + ": new version " + pkg.mVersionCode 7996 + " better than installed " + ps.versionCode); 7997 7998 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7999 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 8000 synchronized (mInstallLock) { 8001 args.cleanUpResourcesLI(); 8002 } 8003 synchronized (mPackages) { 8004 mSettings.enableSystemPackageLPw(ps.name); 8005 } 8006 updatedPkgBetter = true; 8007 } 8008 } 8009 } 8010 8011 if (updatedPkg != null) { 8012 // An updated system app will not have the PARSE_IS_SYSTEM flag set 8013 // initially 8014 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 8015 8016 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 8017 // flag set initially 8018 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 8019 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 8020 } 8021 } 8022 8023 // Verify certificates against what was last scanned 8024 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 8025 8026 /* 8027 * A new system app appeared, but we already had a non-system one of the 8028 * same name installed earlier. 8029 */ 8030 boolean shouldHideSystemApp = false; 8031 if (updatedPkg == null && ps != null 8032 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 8033 /* 8034 * Check to make sure the signatures match first. If they don't, 8035 * wipe the installed application and its data. 8036 */ 8037 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 8038 != PackageManager.SIGNATURE_MATCH) { 8039 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 8040 + " signatures don't match existing userdata copy; removing"); 8041 try (PackageFreezer freezer = freezePackage(pkg.packageName, 8042 "scanPackageInternalLI")) { 8043 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 8044 } 8045 ps = null; 8046 } else { 8047 /* 8048 * If the newly-added system app is an older version than the 8049 * already installed version, hide it. It will be scanned later 8050 * and re-added like an update. 8051 */ 8052 if (pkg.mVersionCode <= ps.versionCode) { 8053 shouldHideSystemApp = true; 8054 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 8055 + " but new version " + pkg.mVersionCode + " better than installed " 8056 + ps.versionCode + "; hiding system"); 8057 } else { 8058 /* 8059 * The newly found system app is a newer version that the 8060 * one previously installed. Simply remove the 8061 * already-installed application and replace it with our own 8062 * while keeping the application data. 8063 */ 8064 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 8065 + " reverting from " + ps.codePathString + ": new version " 8066 + pkg.mVersionCode + " better than installed " + ps.versionCode); 8067 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 8068 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 8069 synchronized (mInstallLock) { 8070 args.cleanUpResourcesLI(); 8071 } 8072 } 8073 } 8074 } 8075 8076 // The apk is forward locked (not public) if its code and resources 8077 // are kept in different files. (except for app in either system or 8078 // vendor path). 8079 // TODO grab this value from PackageSettings 8080 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8081 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 8082 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 8083 } 8084 } 8085 8086 // TODO: extend to support forward-locked splits 8087 String resourcePath = null; 8088 String baseResourcePath = null; 8089 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 8090 if (ps != null && ps.resourcePathString != null) { 8091 resourcePath = ps.resourcePathString; 8092 baseResourcePath = ps.resourcePathString; 8093 } else { 8094 // Should not happen at all. Just log an error. 8095 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 8096 } 8097 } else { 8098 resourcePath = pkg.codePath; 8099 baseResourcePath = pkg.baseCodePath; 8100 } 8101 8102 // Set application objects path explicitly. 8103 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 8104 pkg.setApplicationInfoCodePath(pkg.codePath); 8105 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 8106 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 8107 pkg.setApplicationInfoResourcePath(resourcePath); 8108 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 8109 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 8110 8111 final int userId = ((user == null) ? 0 : user.getIdentifier()); 8112 if (ps != null && ps.getInstantApp(userId)) { 8113 scanFlags |= SCAN_AS_INSTANT_APP; 8114 } 8115 8116 // Note that we invoke the following method only if we are about to unpack an application 8117 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 8118 | SCAN_UPDATE_SIGNATURE, currentTime, user); 8119 8120 /* 8121 * If the system app should be overridden by a previously installed 8122 * data, hide the system app now and let the /data/app scan pick it up 8123 * again. 8124 */ 8125 if (shouldHideSystemApp) { 8126 synchronized (mPackages) { 8127 mSettings.disableSystemPackageLPw(pkg.packageName, true); 8128 } 8129 } 8130 8131 return scannedPkg; 8132 } 8133 8134 private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) { 8135 // Derive the new package synthetic package name 8136 pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER 8137 + pkg.staticSharedLibVersion); 8138 } 8139 8140 private static String fixProcessName(String defProcessName, 8141 String processName) { 8142 if (processName == null) { 8143 return defProcessName; 8144 } 8145 return processName; 8146 } 8147 8148 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 8149 throws PackageManagerException { 8150 if (pkgSetting.signatures.mSignatures != null) { 8151 // Already existing package. Make sure signatures match 8152 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 8153 == PackageManager.SIGNATURE_MATCH; 8154 if (!match) { 8155 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 8156 == PackageManager.SIGNATURE_MATCH; 8157 } 8158 if (!match) { 8159 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 8160 == PackageManager.SIGNATURE_MATCH; 8161 } 8162 if (!match) { 8163 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 8164 + pkg.packageName + " signatures do not match the " 8165 + "previously installed version; ignoring!"); 8166 } 8167 } 8168 8169 // Check for shared user signatures 8170 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 8171 // Already existing package. Make sure signatures match 8172 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8173 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 8174 if (!match) { 8175 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 8176 == PackageManager.SIGNATURE_MATCH; 8177 } 8178 if (!match) { 8179 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 8180 == PackageManager.SIGNATURE_MATCH; 8181 } 8182 if (!match) { 8183 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 8184 "Package " + pkg.packageName 8185 + " has no signatures that match those in shared user " 8186 + pkgSetting.sharedUser.name + "; ignoring!"); 8187 } 8188 } 8189 } 8190 8191 /** 8192 * Enforces that only the system UID or root's UID can call a method exposed 8193 * via Binder. 8194 * 8195 * @param message used as message if SecurityException is thrown 8196 * @throws SecurityException if the caller is not system or root 8197 */ 8198 private static final void enforceSystemOrRoot(String message) { 8199 final int uid = Binder.getCallingUid(); 8200 if (uid != Process.SYSTEM_UID && uid != 0) { 8201 throw new SecurityException(message); 8202 } 8203 } 8204 8205 @Override 8206 public void performFstrimIfNeeded() { 8207 enforceSystemOrRoot("Only the system can request fstrim"); 8208 8209 // Before everything else, see whether we need to fstrim. 8210 try { 8211 IStorageManager sm = PackageHelper.getStorageManager(); 8212 if (sm != null) { 8213 boolean doTrim = false; 8214 final long interval = android.provider.Settings.Global.getLong( 8215 mContext.getContentResolver(), 8216 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 8217 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 8218 if (interval > 0) { 8219 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance(); 8220 if (timeSinceLast > interval) { 8221 doTrim = true; 8222 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 8223 + "; running immediately"); 8224 } 8225 } 8226 if (doTrim) { 8227 final boolean dexOptDialogShown; 8228 synchronized (mPackages) { 8229 dexOptDialogShown = mDexOptDialogShown; 8230 } 8231 if (!isFirstBoot() && dexOptDialogShown) { 8232 try { 8233 ActivityManager.getService().showBootMessage( 8234 mContext.getResources().getString( 8235 R.string.android_upgrading_fstrim), true); 8236 } catch (RemoteException e) { 8237 } 8238 } 8239 sm.runMaintenance(); 8240 } 8241 } else { 8242 Slog.e(TAG, "storageManager service unavailable!"); 8243 } 8244 } catch (RemoteException e) { 8245 // Can't happen; StorageManagerService is local 8246 } 8247 } 8248 8249 @Override 8250 public void updatePackagesIfNeeded() { 8251 enforceSystemOrRoot("Only the system can request package update"); 8252 8253 // We need to re-extract after an OTA. 8254 boolean causeUpgrade = isUpgrade(); 8255 8256 // First boot or factory reset. 8257 // Note: we also handle devices that are upgrading to N right now as if it is their 8258 // first boot, as they do not have profile data. 8259 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 8260 8261 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 8262 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 8263 8264 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 8265 return; 8266 } 8267 8268 List<PackageParser.Package> pkgs; 8269 synchronized (mPackages) { 8270 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 8271 } 8272 8273 final long startTime = System.nanoTime(); 8274 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 8275 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 8276 8277 final int elapsedTimeSeconds = 8278 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 8279 8280 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 8281 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 8282 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 8283 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 8284 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 8285 } 8286 8287 /** 8288 * Performs dexopt on the set of packages in {@code packages} and returns an int array 8289 * containing statistics about the invocation. The array consists of three elements, 8290 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 8291 * and {@code numberOfPackagesFailed}. 8292 */ 8293 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 8294 String compilerFilter) { 8295 8296 int numberOfPackagesVisited = 0; 8297 int numberOfPackagesOptimized = 0; 8298 int numberOfPackagesSkipped = 0; 8299 int numberOfPackagesFailed = 0; 8300 final int numberOfPackagesToDexopt = pkgs.size(); 8301 8302 for (PackageParser.Package pkg : pkgs) { 8303 numberOfPackagesVisited++; 8304 8305 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 8306 if (DEBUG_DEXOPT) { 8307 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 8308 } 8309 numberOfPackagesSkipped++; 8310 continue; 8311 } 8312 8313 if (DEBUG_DEXOPT) { 8314 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 8315 numberOfPackagesToDexopt + ": " + pkg.packageName); 8316 } 8317 8318 if (showDialog) { 8319 try { 8320 ActivityManager.getService().showBootMessage( 8321 mContext.getResources().getString(R.string.android_upgrading_apk, 8322 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 8323 } catch (RemoteException e) { 8324 } 8325 synchronized (mPackages) { 8326 mDexOptDialogShown = true; 8327 } 8328 } 8329 8330 // If the OTA updates a system app which was previously preopted to a non-preopted state 8331 // the app might end up being verified at runtime. That's because by default the apps 8332 // are verify-profile but for preopted apps there's no profile. 8333 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 8334 // that before the OTA the app was preopted) the app gets compiled with a non-profile 8335 // filter (by default interpret-only). 8336 // Note that at this stage unused apps are already filtered. 8337 if (isSystemApp(pkg) && 8338 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 8339 !Environment.getReferenceProfile(pkg.packageName).exists()) { 8340 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 8341 } 8342 8343 // checkProfiles is false to avoid merging profiles during boot which 8344 // might interfere with background compilation (b/28612421). 8345 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 8346 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 8347 // trade-off worth doing to save boot time work. 8348 int dexOptStatus = performDexOptTraced(pkg.packageName, 8349 false /* checkProfiles */, 8350 compilerFilter, 8351 false /* force */); 8352 switch (dexOptStatus) { 8353 case PackageDexOptimizer.DEX_OPT_PERFORMED: 8354 numberOfPackagesOptimized++; 8355 break; 8356 case PackageDexOptimizer.DEX_OPT_SKIPPED: 8357 numberOfPackagesSkipped++; 8358 break; 8359 case PackageDexOptimizer.DEX_OPT_FAILED: 8360 numberOfPackagesFailed++; 8361 break; 8362 default: 8363 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 8364 break; 8365 } 8366 } 8367 8368 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 8369 numberOfPackagesFailed }; 8370 } 8371 8372 @Override 8373 public void notifyPackageUse(String packageName, int reason) { 8374 synchronized (mPackages) { 8375 PackageParser.Package p = mPackages.get(packageName); 8376 if (p == null) { 8377 return; 8378 } 8379 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 8380 } 8381 } 8382 8383 @Override 8384 public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) { 8385 int userId = UserHandle.getCallingUserId(); 8386 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId); 8387 if (ai == null) { 8388 Slog.w(TAG, "Loading a package that does not exist for the calling user. package=" 8389 + loadingPackageName + ", user=" + userId); 8390 return; 8391 } 8392 mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId); 8393 } 8394 8395 // TODO: this is not used nor needed. Delete it. 8396 @Override 8397 public boolean performDexOptIfNeeded(String packageName) { 8398 int dexOptStatus = performDexOptTraced(packageName, 8399 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 8400 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8401 } 8402 8403 @Override 8404 public boolean performDexOpt(String packageName, 8405 boolean checkProfiles, int compileReason, boolean force) { 8406 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 8407 getCompilerFilterForReason(compileReason), force); 8408 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8409 } 8410 8411 @Override 8412 public boolean performDexOptMode(String packageName, 8413 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8414 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 8415 targetCompilerFilter, force); 8416 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 8417 } 8418 8419 private int performDexOptTraced(String packageName, 8420 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8421 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 8422 try { 8423 return performDexOptInternal(packageName, checkProfiles, 8424 targetCompilerFilter, force); 8425 } finally { 8426 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8427 } 8428 } 8429 8430 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 8431 // if the package can now be considered up to date for the given filter. 8432 private int performDexOptInternal(String packageName, 8433 boolean checkProfiles, String targetCompilerFilter, boolean force) { 8434 PackageParser.Package p; 8435 synchronized (mPackages) { 8436 p = mPackages.get(packageName); 8437 if (p == null) { 8438 // Package could not be found. Report failure. 8439 return PackageDexOptimizer.DEX_OPT_FAILED; 8440 } 8441 mPackageUsage.maybeWriteAsync(mPackages); 8442 mCompilerStats.maybeWriteAsync(); 8443 } 8444 long callingId = Binder.clearCallingIdentity(); 8445 try { 8446 synchronized (mInstallLock) { 8447 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 8448 targetCompilerFilter, force); 8449 } 8450 } finally { 8451 Binder.restoreCallingIdentity(callingId); 8452 } 8453 } 8454 8455 public ArraySet<String> getOptimizablePackages() { 8456 ArraySet<String> pkgs = new ArraySet<String>(); 8457 synchronized (mPackages) { 8458 for (PackageParser.Package p : mPackages.values()) { 8459 if (PackageDexOptimizer.canOptimizePackage(p)) { 8460 pkgs.add(p.packageName); 8461 } 8462 } 8463 } 8464 return pkgs; 8465 } 8466 8467 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 8468 boolean checkProfiles, String targetCompilerFilter, 8469 boolean force) { 8470 // Select the dex optimizer based on the force parameter. 8471 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 8472 // allocate an object here. 8473 PackageDexOptimizer pdo = force 8474 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 8475 : mPackageDexOptimizer; 8476 8477 // Optimize all dependencies first. Note: we ignore the return value and march on 8478 // on errors. 8479 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 8480 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 8481 if (!deps.isEmpty()) { 8482 for (PackageParser.Package depPackage : deps) { 8483 // TODO: Analyze and investigate if we (should) profile libraries. 8484 // Currently this will do a full compilation of the library by default. 8485 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 8486 false /* checkProfiles */, 8487 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 8488 getOrCreateCompilerPackageStats(depPackage), 8489 mDexManager.isUsedByOtherApps(p.packageName)); 8490 } 8491 } 8492 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 8493 targetCompilerFilter, getOrCreateCompilerPackageStats(p), 8494 mDexManager.isUsedByOtherApps(p.packageName)); 8495 } 8496 8497 // Performs dexopt on the used secondary dex files belonging to the given package. 8498 // Returns true if all dex files were process successfully (which could mean either dexopt or 8499 // skip). Returns false if any of the files caused errors. 8500 @Override 8501 public boolean performDexOptSecondary(String packageName, String compilerFilter, 8502 boolean force) { 8503 return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); 8504 } 8505 8506 public boolean performDexOptSecondary(String packageName, int compileReason, 8507 boolean force) { 8508 return mDexManager.dexoptSecondaryDex(packageName, compileReason, force); 8509 } 8510 8511 /** 8512 * Reconcile the information we have about the secondary dex files belonging to 8513 * {@code packagName} and the actual dex files. For all dex files that were 8514 * deleted, update the internal records and delete the generated oat files. 8515 */ 8516 @Override 8517 public void reconcileSecondaryDexFiles(String packageName) { 8518 mDexManager.reconcileSecondaryDexFiles(packageName); 8519 } 8520 8521 // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject 8522 // a reference there. 8523 /*package*/ DexManager getDexManager() { 8524 return mDexManager; 8525 } 8526 8527 /** 8528 * Execute the background dexopt job immediately. 8529 */ 8530 @Override 8531 public boolean runBackgroundDexoptJob() { 8532 return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext); 8533 } 8534 8535 List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 8536 if (p.usesLibraries != null || p.usesOptionalLibraries != null 8537 || p.usesStaticLibraries != null) { 8538 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 8539 Set<String> collectedNames = new HashSet<>(); 8540 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 8541 8542 retValue.remove(p); 8543 8544 return retValue; 8545 } else { 8546 return Collections.emptyList(); 8547 } 8548 } 8549 8550 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 8551 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) { 8552 if (!collectedNames.contains(p.packageName)) { 8553 collectedNames.add(p.packageName); 8554 collected.add(p); 8555 8556 if (p.usesLibraries != null) { 8557 findSharedNonSystemLibrariesRecursive(p.usesLibraries, 8558 null, collected, collectedNames); 8559 } 8560 if (p.usesOptionalLibraries != null) { 8561 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, 8562 null, collected, collectedNames); 8563 } 8564 if (p.usesStaticLibraries != null) { 8565 findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries, 8566 p.usesStaticLibrariesVersions, collected, collectedNames); 8567 } 8568 } 8569 } 8570 8571 private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions, 8572 ArrayList<PackageParser.Package> collected, Set<String> collectedNames) { 8573 final int libNameCount = libs.size(); 8574 for (int i = 0; i < libNameCount; i++) { 8575 String libName = libs.get(i); 8576 int version = (versions != null && versions.length == libNameCount) 8577 ? versions[i] : PackageManager.VERSION_CODE_HIGHEST; 8578 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version); 8579 if (libPkg != null) { 8580 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 8581 } 8582 } 8583 } 8584 8585 private PackageParser.Package findSharedNonSystemLibrary(String name, int version) { 8586 synchronized (mPackages) { 8587 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version); 8588 if (libEntry != null) { 8589 return mPackages.get(libEntry.apk); 8590 } 8591 return null; 8592 } 8593 } 8594 8595 private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) { 8596 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 8597 if (versionedLib == null) { 8598 return null; 8599 } 8600 return versionedLib.get(version); 8601 } 8602 8603 private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) { 8604 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get( 8605 pkg.staticSharedLibName); 8606 if (versionedLib == null) { 8607 return null; 8608 } 8609 int previousLibVersion = -1; 8610 final int versionCount = versionedLib.size(); 8611 for (int i = 0; i < versionCount; i++) { 8612 final int libVersion = versionedLib.keyAt(i); 8613 if (libVersion < pkg.staticSharedLibVersion) { 8614 previousLibVersion = Math.max(previousLibVersion, libVersion); 8615 } 8616 } 8617 if (previousLibVersion >= 0) { 8618 return versionedLib.get(previousLibVersion); 8619 } 8620 return null; 8621 } 8622 8623 public void shutdown() { 8624 mPackageUsage.writeNow(mPackages); 8625 mCompilerStats.writeNow(); 8626 } 8627 8628 @Override 8629 public void dumpProfiles(String packageName) { 8630 PackageParser.Package pkg; 8631 synchronized (mPackages) { 8632 pkg = mPackages.get(packageName); 8633 if (pkg == null) { 8634 throw new IllegalArgumentException("Unknown package: " + packageName); 8635 } 8636 } 8637 /* Only the shell, root, or the app user should be able to dump profiles. */ 8638 int callingUid = Binder.getCallingUid(); 8639 if (callingUid != Process.SHELL_UID && 8640 callingUid != Process.ROOT_UID && 8641 callingUid != pkg.applicationInfo.uid) { 8642 throw new SecurityException("dumpProfiles"); 8643 } 8644 8645 synchronized (mInstallLock) { 8646 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 8647 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 8648 try { 8649 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 8650 String codePaths = TextUtils.join(";", allCodePaths); 8651 mInstaller.dumpProfiles(sharedGid, packageName, codePaths); 8652 } catch (InstallerException e) { 8653 Slog.w(TAG, "Failed to dump profiles", e); 8654 } 8655 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8656 } 8657 } 8658 8659 @Override 8660 public void forceDexOpt(String packageName) { 8661 enforceSystemOrRoot("forceDexOpt"); 8662 8663 PackageParser.Package pkg; 8664 synchronized (mPackages) { 8665 pkg = mPackages.get(packageName); 8666 if (pkg == null) { 8667 throw new IllegalArgumentException("Unknown package: " + packageName); 8668 } 8669 } 8670 8671 synchronized (mInstallLock) { 8672 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 8673 8674 // Whoever is calling forceDexOpt wants a fully compiled package. 8675 // Don't use profiles since that may cause compilation to be skipped. 8676 final int res = performDexOptInternalWithDependenciesLI(pkg, 8677 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 8678 true /* force */); 8679 8680 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8681 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 8682 throw new IllegalStateException("Failed to dexopt: " + res); 8683 } 8684 } 8685 } 8686 8687 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 8688 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8689 Slog.w(TAG, "Unable to update from " + oldPkg.name 8690 + " to " + newPkg.packageName 8691 + ": old package not in system partition"); 8692 return false; 8693 } else if (mPackages.get(oldPkg.name) != null) { 8694 Slog.w(TAG, "Unable to update from " + oldPkg.name 8695 + " to " + newPkg.packageName 8696 + ": old package still exists"); 8697 return false; 8698 } 8699 return true; 8700 } 8701 8702 void removeCodePathLI(File codePath) { 8703 if (codePath.isDirectory()) { 8704 try { 8705 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 8706 } catch (InstallerException e) { 8707 Slog.w(TAG, "Failed to remove code path", e); 8708 } 8709 } else { 8710 codePath.delete(); 8711 } 8712 } 8713 8714 private int[] resolveUserIds(int userId) { 8715 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 8716 } 8717 8718 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 8719 if (pkg == null) { 8720 Slog.wtf(TAG, "Package was null!", new Throwable()); 8721 return; 8722 } 8723 clearAppDataLeafLIF(pkg, userId, flags); 8724 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8725 for (int i = 0; i < childCount; i++) { 8726 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 8727 } 8728 } 8729 8730 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 8731 final PackageSetting ps; 8732 synchronized (mPackages) { 8733 ps = mSettings.mPackages.get(pkg.packageName); 8734 } 8735 for (int realUserId : resolveUserIds(userId)) { 8736 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 8737 try { 8738 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 8739 ceDataInode); 8740 } catch (InstallerException e) { 8741 Slog.w(TAG, String.valueOf(e)); 8742 } 8743 } 8744 } 8745 8746 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 8747 if (pkg == null) { 8748 Slog.wtf(TAG, "Package was null!", new Throwable()); 8749 return; 8750 } 8751 destroyAppDataLeafLIF(pkg, userId, flags); 8752 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8753 for (int i = 0; i < childCount; i++) { 8754 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 8755 } 8756 } 8757 8758 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 8759 final PackageSetting ps; 8760 synchronized (mPackages) { 8761 ps = mSettings.mPackages.get(pkg.packageName); 8762 } 8763 for (int realUserId : resolveUserIds(userId)) { 8764 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 8765 try { 8766 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 8767 ceDataInode); 8768 } catch (InstallerException e) { 8769 Slog.w(TAG, String.valueOf(e)); 8770 } 8771 mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId); 8772 } 8773 } 8774 8775 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 8776 if (pkg == null) { 8777 Slog.wtf(TAG, "Package was null!", new Throwable()); 8778 return; 8779 } 8780 destroyAppProfilesLeafLIF(pkg); 8781 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8782 for (int i = 0; i < childCount; i++) { 8783 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 8784 } 8785 } 8786 8787 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 8788 try { 8789 mInstaller.destroyAppProfiles(pkg.packageName); 8790 } catch (InstallerException e) { 8791 Slog.w(TAG, String.valueOf(e)); 8792 } 8793 } 8794 8795 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 8796 if (pkg == null) { 8797 Slog.wtf(TAG, "Package was null!", new Throwable()); 8798 return; 8799 } 8800 clearAppProfilesLeafLIF(pkg); 8801 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8802 for (int i = 0; i < childCount; i++) { 8803 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 8804 } 8805 } 8806 8807 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 8808 try { 8809 mInstaller.clearAppProfiles(pkg.packageName); 8810 } catch (InstallerException e) { 8811 Slog.w(TAG, String.valueOf(e)); 8812 } 8813 } 8814 8815 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 8816 long lastUpdateTime) { 8817 // Set parent install/update time 8818 PackageSetting ps = (PackageSetting) pkg.mExtras; 8819 if (ps != null) { 8820 ps.firstInstallTime = firstInstallTime; 8821 ps.lastUpdateTime = lastUpdateTime; 8822 } 8823 // Set children install/update time 8824 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8825 for (int i = 0; i < childCount; i++) { 8826 PackageParser.Package childPkg = pkg.childPackages.get(i); 8827 ps = (PackageSetting) childPkg.mExtras; 8828 if (ps != null) { 8829 ps.firstInstallTime = firstInstallTime; 8830 ps.lastUpdateTime = lastUpdateTime; 8831 } 8832 } 8833 } 8834 8835 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 8836 PackageParser.Package changingLib) { 8837 if (file.path != null) { 8838 usesLibraryFiles.add(file.path); 8839 return; 8840 } 8841 PackageParser.Package p = mPackages.get(file.apk); 8842 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 8843 // If we are doing this while in the middle of updating a library apk, 8844 // then we need to make sure to use that new apk for determining the 8845 // dependencies here. (We haven't yet finished committing the new apk 8846 // to the package manager state.) 8847 if (p == null || p.packageName.equals(changingLib.packageName)) { 8848 p = changingLib; 8849 } 8850 } 8851 if (p != null) { 8852 usesLibraryFiles.addAll(p.getAllCodePaths()); 8853 } 8854 } 8855 8856 private void updateSharedLibrariesLPr(PackageParser.Package pkg, 8857 PackageParser.Package changingLib) throws PackageManagerException { 8858 if (pkg == null) { 8859 return; 8860 } 8861 ArraySet<String> usesLibraryFiles = null; 8862 if (pkg.usesLibraries != null) { 8863 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries, 8864 null, null, pkg.packageName, changingLib, true, null); 8865 } 8866 if (pkg.usesStaticLibraries != null) { 8867 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries, 8868 pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests, 8869 pkg.packageName, changingLib, true, usesLibraryFiles); 8870 } 8871 if (pkg.usesOptionalLibraries != null) { 8872 usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries, 8873 null, null, pkg.packageName, changingLib, false, usesLibraryFiles); 8874 } 8875 if (!ArrayUtils.isEmpty(usesLibraryFiles)) { 8876 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]); 8877 } else { 8878 pkg.usesLibraryFiles = null; 8879 } 8880 } 8881 8882 private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries, 8883 @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests, 8884 @NonNull String packageName, @Nullable PackageParser.Package changingLib, 8885 boolean required, @Nullable ArraySet<String> outUsedLibraries) 8886 throws PackageManagerException { 8887 final int libCount = requestedLibraries.size(); 8888 for (int i = 0; i < libCount; i++) { 8889 final String libName = requestedLibraries.get(i); 8890 final int libVersion = requiredVersions != null ? requiredVersions[i] 8891 : SharedLibraryInfo.VERSION_UNDEFINED; 8892 final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion); 8893 if (libEntry == null) { 8894 if (required) { 8895 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8896 "Package " + packageName + " requires unavailable shared library " 8897 + libName + "; failing!"); 8898 } else { 8899 Slog.w(TAG, "Package " + packageName 8900 + " desires unavailable shared library " 8901 + libName + "; ignoring!"); 8902 } 8903 } else { 8904 if (requiredVersions != null && requiredCertDigests != null) { 8905 if (libEntry.info.getVersion() != requiredVersions[i]) { 8906 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8907 "Package " + packageName + " requires unavailable static shared" 8908 + " library " + libName + " version " 8909 + libEntry.info.getVersion() + "; failing!"); 8910 } 8911 8912 PackageParser.Package libPkg = mPackages.get(libEntry.apk); 8913 if (libPkg == null) { 8914 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8915 "Package " + packageName + " requires unavailable static shared" 8916 + " library; failing!"); 8917 } 8918 8919 String expectedCertDigest = requiredCertDigests[i]; 8920 String libCertDigest = PackageUtils.computeCertSha256Digest( 8921 libPkg.mSignatures[0]); 8922 if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) { 8923 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8924 "Package " + packageName + " requires differently signed" + 8925 " static shared library; failing!"); 8926 } 8927 } 8928 8929 if (outUsedLibraries == null) { 8930 outUsedLibraries = new ArraySet<>(); 8931 } 8932 addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib); 8933 } 8934 } 8935 return outUsedLibraries; 8936 } 8937 8938 private static boolean hasString(List<String> list, List<String> which) { 8939 if (list == null) { 8940 return false; 8941 } 8942 for (int i=list.size()-1; i>=0; i--) { 8943 for (int j=which.size()-1; j>=0; j--) { 8944 if (which.get(j).equals(list.get(i))) { 8945 return true; 8946 } 8947 } 8948 } 8949 return false; 8950 } 8951 8952 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 8953 PackageParser.Package changingPkg) { 8954 ArrayList<PackageParser.Package> res = null; 8955 for (PackageParser.Package pkg : mPackages.values()) { 8956 if (changingPkg != null 8957 && !hasString(pkg.usesLibraries, changingPkg.libraryNames) 8958 && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames) 8959 && !ArrayUtils.contains(pkg.usesStaticLibraries, 8960 changingPkg.staticSharedLibName)) { 8961 return null; 8962 } 8963 if (res == null) { 8964 res = new ArrayList<>(); 8965 } 8966 res.add(pkg); 8967 try { 8968 updateSharedLibrariesLPr(pkg, changingPkg); 8969 } catch (PackageManagerException e) { 8970 // If a system app update or an app and a required lib missing we 8971 // delete the package and for updated system apps keep the data as 8972 // it is better for the user to reinstall than to be in an limbo 8973 // state. Also libs disappearing under an app should never happen 8974 // - just in case. 8975 if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) { 8976 final int flags = pkg.isUpdatedSystemApp() 8977 ? PackageManager.DELETE_KEEP_DATA : 0; 8978 deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(), 8979 flags , null, true, null); 8980 } 8981 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 8982 } 8983 } 8984 return res; 8985 } 8986 8987 /** 8988 * Derive the value of the {@code cpuAbiOverride} based on the provided 8989 * value and an optional stored value from the package settings. 8990 */ 8991 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 8992 String cpuAbiOverride = null; 8993 8994 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 8995 cpuAbiOverride = null; 8996 } else if (abiOverride != null) { 8997 cpuAbiOverride = abiOverride; 8998 } else if (settings != null) { 8999 cpuAbiOverride = settings.cpuAbiOverrideString; 9000 } 9001 9002 return cpuAbiOverride; 9003 } 9004 9005 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 9006 final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) 9007 throws PackageManagerException { 9008 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 9009 // If the package has children and this is the first dive in the function 9010 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 9011 // whether all packages (parent and children) would be successfully scanned 9012 // before the actual scan since scanning mutates internal state and we want 9013 // to atomically install the package and its children. 9014 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 9015 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 9016 scanFlags |= SCAN_CHECK_ONLY; 9017 } 9018 } else { 9019 scanFlags &= ~SCAN_CHECK_ONLY; 9020 } 9021 9022 final PackageParser.Package scannedPkg; 9023 try { 9024 // Scan the parent 9025 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 9026 // Scan the children 9027 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9028 for (int i = 0; i < childCount; i++) { 9029 PackageParser.Package childPkg = pkg.childPackages.get(i); 9030 scanPackageLI(childPkg, policyFlags, 9031 scanFlags, currentTime, user); 9032 } 9033 } finally { 9034 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9035 } 9036 9037 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 9038 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 9039 } 9040 9041 return scannedPkg; 9042 } 9043 9044 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 9045 int scanFlags, long currentTime, @Nullable UserHandle user) 9046 throws PackageManagerException { 9047 boolean success = false; 9048 try { 9049 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 9050 currentTime, user); 9051 success = true; 9052 return res; 9053 } finally { 9054 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 9055 // DELETE_DATA_ON_FAILURES is only used by frozen paths 9056 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 9057 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 9058 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 9059 } 9060 } 9061 } 9062 9063 /** 9064 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 9065 */ 9066 private static boolean apkHasCode(String fileName) { 9067 StrictJarFile jarFile = null; 9068 try { 9069 jarFile = new StrictJarFile(fileName, 9070 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 9071 return jarFile.findEntry("classes.dex") != null; 9072 } catch (IOException ignore) { 9073 } finally { 9074 try { 9075 if (jarFile != null) { 9076 jarFile.close(); 9077 } 9078 } catch (IOException ignore) {} 9079 } 9080 return false; 9081 } 9082 9083 /** 9084 * Enforces code policy for the package. This ensures that if an APK has 9085 * declared hasCode="true" in its manifest that the APK actually contains 9086 * code. 9087 * 9088 * @throws PackageManagerException If bytecode could not be found when it should exist 9089 */ 9090 private static void assertCodePolicy(PackageParser.Package pkg) 9091 throws PackageManagerException { 9092 final boolean shouldHaveCode = 9093 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 9094 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 9095 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 9096 "Package " + pkg.baseCodePath + " code is missing"); 9097 } 9098 9099 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 9100 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 9101 final boolean splitShouldHaveCode = 9102 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 9103 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 9104 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 9105 "Package " + pkg.splitCodePaths[i] + " code is missing"); 9106 } 9107 } 9108 } 9109 } 9110 9111 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 9112 final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user) 9113 throws PackageManagerException { 9114 if (DEBUG_PACKAGE_SCANNING) { 9115 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 9116 Log.d(TAG, "Scanning package " + pkg.packageName); 9117 } 9118 9119 applyPolicy(pkg, policyFlags); 9120 9121 assertPackageIsValid(pkg, policyFlags, scanFlags); 9122 9123 // Initialize package source and resource directories 9124 final File scanFile = new File(pkg.codePath); 9125 final File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 9126 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 9127 9128 SharedUserSetting suid = null; 9129 PackageSetting pkgSetting = null; 9130 9131 // Getting the package setting may have a side-effect, so if we 9132 // are only checking if scan would succeed, stash a copy of the 9133 // old setting to restore at the end. 9134 PackageSetting nonMutatedPs = null; 9135 9136 // We keep references to the derived CPU Abis from settings in oder to reuse 9137 // them in the case where we're not upgrading or booting for the first time. 9138 String primaryCpuAbiFromSettings = null; 9139 String secondaryCpuAbiFromSettings = null; 9140 9141 // writer 9142 synchronized (mPackages) { 9143 if (pkg.mSharedUserId != null) { 9144 // SIDE EFFECTS; may potentially allocate a new shared user 9145 suid = mSettings.getSharedUserLPw( 9146 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); 9147 if (DEBUG_PACKAGE_SCANNING) { 9148 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 9149 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 9150 + "): packages=" + suid.packages); 9151 } 9152 } 9153 9154 // Check if we are renaming from an original package name. 9155 PackageSetting origPackage = null; 9156 String realName = null; 9157 if (pkg.mOriginalPackages != null) { 9158 // This package may need to be renamed to a previously 9159 // installed name. Let's check on that... 9160 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage); 9161 if (pkg.mOriginalPackages.contains(renamed)) { 9162 // This package had originally been installed as the 9163 // original name, and we have already taken care of 9164 // transitioning to the new one. Just update the new 9165 // one to continue using the old name. 9166 realName = pkg.mRealPackage; 9167 if (!pkg.packageName.equals(renamed)) { 9168 // Callers into this function may have already taken 9169 // care of renaming the package; only do it here if 9170 // it is not already done. 9171 pkg.setPackageName(renamed); 9172 } 9173 } else { 9174 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 9175 if ((origPackage = mSettings.getPackageLPr( 9176 pkg.mOriginalPackages.get(i))) != null) { 9177 // We do have the package already installed under its 9178 // original name... should we use it? 9179 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 9180 // New package is not compatible with original. 9181 origPackage = null; 9182 continue; 9183 } else if (origPackage.sharedUser != null) { 9184 // Make sure uid is compatible between packages. 9185 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 9186 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 9187 + " to " + pkg.packageName + ": old uid " 9188 + origPackage.sharedUser.name 9189 + " differs from " + pkg.mSharedUserId); 9190 origPackage = null; 9191 continue; 9192 } 9193 // TODO: Add case when shared user id is added [b/28144775] 9194 } else { 9195 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 9196 + pkg.packageName + " to old name " + origPackage.name); 9197 } 9198 break; 9199 } 9200 } 9201 } 9202 } 9203 9204 if (mTransferedPackages.contains(pkg.packageName)) { 9205 Slog.w(TAG, "Package " + pkg.packageName 9206 + " was transferred to another, but its .apk remains"); 9207 } 9208 9209 // See comments in nonMutatedPs declaration 9210 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 9211 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 9212 if (foundPs != null) { 9213 nonMutatedPs = new PackageSetting(foundPs); 9214 } 9215 } 9216 9217 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) { 9218 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 9219 if (foundPs != null) { 9220 primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString; 9221 secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString; 9222 } 9223 } 9224 9225 pkgSetting = mSettings.getPackageLPr(pkg.packageName); 9226 if (pkgSetting != null && pkgSetting.sharedUser != suid) { 9227 PackageManagerService.reportSettingsProblem(Log.WARN, 9228 "Package " + pkg.packageName + " shared user changed from " 9229 + (pkgSetting.sharedUser != null 9230 ? pkgSetting.sharedUser.name : "<nothing>") 9231 + " to " 9232 + (suid != null ? suid.name : "<nothing>") 9233 + "; replacing with new"); 9234 pkgSetting = null; 9235 } 9236 final PackageSetting oldPkgSetting = 9237 pkgSetting == null ? null : new PackageSetting(pkgSetting); 9238 final PackageSetting disabledPkgSetting = 9239 mSettings.getDisabledSystemPkgLPr(pkg.packageName); 9240 9241 String[] usesStaticLibraries = null; 9242 if (pkg.usesStaticLibraries != null) { 9243 usesStaticLibraries = new String[pkg.usesStaticLibraries.size()]; 9244 pkg.usesStaticLibraries.toArray(usesStaticLibraries); 9245 } 9246 9247 if (pkgSetting == null) { 9248 final String parentPackageName = (pkg.parentPackage != null) 9249 ? pkg.parentPackage.packageName : null; 9250 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 9251 // REMOVE SharedUserSetting from method; update in a separate call 9252 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage, 9253 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile, 9254 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi, 9255 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode, 9256 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user, 9257 true /*allowInstall*/, instantApp, parentPackageName, 9258 pkg.getChildPackageNames(), UserManagerService.getInstance(), 9259 usesStaticLibraries, pkg.usesStaticLibrariesVersions); 9260 // SIDE EFFECTS; updates system state; move elsewhere 9261 if (origPackage != null) { 9262 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name); 9263 } 9264 mSettings.addUserToSettingLPw(pkgSetting); 9265 } else { 9266 // REMOVE SharedUserSetting from method; update in a separate call. 9267 // 9268 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi, 9269 // secondaryCpuAbi are not known at this point so we always update them 9270 // to null here, only to reset them at a later point. 9271 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile, 9272 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi, 9273 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags, 9274 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(), 9275 UserManagerService.getInstance(), usesStaticLibraries, 9276 pkg.usesStaticLibrariesVersions); 9277 } 9278 // SIDE EFFECTS; persists system state to files on disk; move elsewhere 9279 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); 9280 9281 // SIDE EFFECTS; modifies system state; move elsewhere 9282 if (pkgSetting.origPackage != null) { 9283 // If we are first transitioning from an original package, 9284 // fix up the new package's name now. We need to do this after 9285 // looking up the package under its new name, so getPackageLP 9286 // can take care of fiddling things correctly. 9287 pkg.setPackageName(origPackage.name); 9288 9289 // File a report about this. 9290 String msg = "New package " + pkgSetting.realName 9291 + " renamed to replace old package " + pkgSetting.name; 9292 reportSettingsProblem(Log.WARN, msg); 9293 9294 // Make a note of it. 9295 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 9296 mTransferedPackages.add(origPackage.name); 9297 } 9298 9299 // No longer need to retain this. 9300 pkgSetting.origPackage = null; 9301 } 9302 9303 // SIDE EFFECTS; modifies system state; move elsewhere 9304 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 9305 // Make a note of it. 9306 mTransferedPackages.add(pkg.packageName); 9307 } 9308 9309 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 9310 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 9311 } 9312 9313 if ((scanFlags & SCAN_BOOTING) == 0 9314 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9315 // Check all shared libraries and map to their actual file path. 9316 // We only do this here for apps not on a system dir, because those 9317 // are the only ones that can fail an install due to this. We 9318 // will take care of the system apps by updating all of their 9319 // library paths after the scan is done. Also during the initial 9320 // scan don't update any libs as we do this wholesale after all 9321 // apps are scanned to avoid dependency based scanning. 9322 updateSharedLibrariesLPr(pkg, null); 9323 } 9324 9325 if (mFoundPolicyFile) { 9326 SELinuxMMAC.assignSeInfoValue(pkg); 9327 } 9328 pkg.applicationInfo.uid = pkgSetting.appId; 9329 pkg.mExtras = pkgSetting; 9330 9331 9332 // Static shared libs have same package with different versions where 9333 // we internally use a synthetic package name to allow multiple versions 9334 // of the same package, therefore we need to compare signatures against 9335 // the package setting for the latest library version. 9336 PackageSetting signatureCheckPs = pkgSetting; 9337 if (pkg.applicationInfo.isStaticSharedLibrary()) { 9338 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg); 9339 if (libraryEntry != null) { 9340 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk); 9341 } 9342 } 9343 9344 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) { 9345 if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) { 9346 // We just determined the app is signed correctly, so bring 9347 // over the latest parsed certs. 9348 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9349 } else { 9350 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9351 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 9352 "Package " + pkg.packageName + " upgrade keys do not match the " 9353 + "previously installed version"); 9354 } else { 9355 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9356 String msg = "System package " + pkg.packageName 9357 + " signature changed; retaining data."; 9358 reportSettingsProblem(Log.WARN, msg); 9359 } 9360 } 9361 } else { 9362 try { 9363 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService 9364 verifySignaturesLP(signatureCheckPs, pkg); 9365 // We just determined the app is signed correctly, so bring 9366 // over the latest parsed certs. 9367 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9368 } catch (PackageManagerException e) { 9369 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 9370 throw e; 9371 } 9372 // The signature has changed, but this package is in the system 9373 // image... let's recover! 9374 pkgSetting.signatures.mSignatures = pkg.mSignatures; 9375 // However... if this package is part of a shared user, but it 9376 // doesn't match the signature of the shared user, let's fail. 9377 // What this means is that you can't change the signatures 9378 // associated with an overall shared user, which doesn't seem all 9379 // that unreasonable. 9380 if (signatureCheckPs.sharedUser != null) { 9381 if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures, 9382 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 9383 throw new PackageManagerException( 9384 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 9385 "Signature mismatch for shared user: " 9386 + pkgSetting.sharedUser); 9387 } 9388 } 9389 // File a report about this. 9390 String msg = "System package " + pkg.packageName 9391 + " signature changed; retaining data."; 9392 reportSettingsProblem(Log.WARN, msg); 9393 } 9394 } 9395 9396 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 9397 // This package wants to adopt ownership of permissions from 9398 // another package. 9399 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 9400 final String origName = pkg.mAdoptPermissions.get(i); 9401 final PackageSetting orig = mSettings.getPackageLPr(origName); 9402 if (orig != null) { 9403 if (verifyPackageUpdateLPr(orig, pkg)) { 9404 Slog.i(TAG, "Adopting permissions from " + origName + " to " 9405 + pkg.packageName); 9406 // SIDE EFFECTS; updates permissions system state; move elsewhere 9407 mSettings.transferPermissionsLPw(origName, pkg.packageName); 9408 } 9409 } 9410 } 9411 } 9412 } 9413 9414 pkg.applicationInfo.processName = fixProcessName( 9415 pkg.applicationInfo.packageName, 9416 pkg.applicationInfo.processName); 9417 9418 if (pkg != mPlatformPackage) { 9419 // Get all of our default paths setup 9420 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 9421 } 9422 9423 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 9424 9425 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 9426 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) { 9427 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); 9428 derivePackageAbi( 9429 pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir); 9430 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9431 9432 // Some system apps still use directory structure for native libraries 9433 // in which case we might end up not detecting abi solely based on apk 9434 // structure. Try to detect abi based on directory structure. 9435 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 9436 pkg.applicationInfo.primaryCpuAbi == null) { 9437 setBundledAppAbisAndRoots(pkg, pkgSetting); 9438 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9439 } 9440 } else { 9441 // This is not a first boot or an upgrade, don't bother deriving the 9442 // ABI during the scan. Instead, trust the value that was stored in the 9443 // package setting. 9444 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; 9445 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings; 9446 9447 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9448 9449 if (DEBUG_ABI_SELECTION) { 9450 Slog.i(TAG, "Using ABIS and native lib paths from settings : " + 9451 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " + 9452 pkg.applicationInfo.secondaryCpuAbi); 9453 } 9454 } 9455 } else { 9456 if ((scanFlags & SCAN_MOVE) != 0) { 9457 // We haven't run dex-opt for this move (since we've moved the compiled output too) 9458 // but we already have this packages package info in the PackageSetting. We just 9459 // use that and derive the native library path based on the new codepath. 9460 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 9461 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 9462 } 9463 9464 // Set native library paths again. For moves, the path will be updated based on the 9465 // ABIs we've determined above. For non-moves, the path will be updated based on the 9466 // ABIs we determined during compilation, but the path will depend on the final 9467 // package path (after the rename away from the stage path). 9468 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 9469 } 9470 9471 // This is a special case for the "system" package, where the ABI is 9472 // dictated by the zygote configuration (and init.rc). We should keep track 9473 // of this ABI so that we can deal with "normal" applications that run under 9474 // the same UID correctly. 9475 if (mPlatformPackage == pkg) { 9476 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 9477 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 9478 } 9479 9480 // If there's a mismatch between the abi-override in the package setting 9481 // and the abiOverride specified for the install. Warn about this because we 9482 // would've already compiled the app without taking the package setting into 9483 // account. 9484 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 9485 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 9486 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 9487 " for package " + pkg.packageName); 9488 } 9489 } 9490 9491 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9492 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9493 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 9494 9495 // Copy the derived override back to the parsed package, so that we can 9496 // update the package settings accordingly. 9497 pkg.cpuAbiOverride = cpuAbiOverride; 9498 9499 if (DEBUG_ABI_SELECTION) { 9500 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 9501 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 9502 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 9503 } 9504 9505 // Push the derived path down into PackageSettings so we know what to 9506 // clean up at uninstall time. 9507 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 9508 9509 if (DEBUG_ABI_SELECTION) { 9510 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 9511 " primary=" + pkg.applicationInfo.primaryCpuAbi + 9512 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 9513 } 9514 9515 // SIDE EFFECTS; removes DEX files from disk; move elsewhere 9516 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 9517 // We don't do this here during boot because we can do it all 9518 // at once after scanning all existing packages. 9519 // 9520 // We also do this *before* we perform dexopt on this package, so that 9521 // we can avoid redundant dexopts, and also to make sure we've got the 9522 // code and package path correct. 9523 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg); 9524 } 9525 9526 if (mFactoryTest && pkg.requestedPermissions.contains( 9527 android.Manifest.permission.FACTORY_TEST)) { 9528 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 9529 } 9530 9531 if (isSystemApp(pkg)) { 9532 pkgSetting.isOrphaned = true; 9533 } 9534 9535 // Take care of first install / last update times. 9536 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 9537 if (currentTime != 0) { 9538 if (pkgSetting.firstInstallTime == 0) { 9539 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 9540 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) { 9541 pkgSetting.lastUpdateTime = currentTime; 9542 } 9543 } else if (pkgSetting.firstInstallTime == 0) { 9544 // We need *something*. Take time time stamp of the file. 9545 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 9546 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 9547 if (scanFileTime != pkgSetting.timeStamp) { 9548 // A package on the system image has changed; consider this 9549 // to be an update. 9550 pkgSetting.lastUpdateTime = scanFileTime; 9551 } 9552 } 9553 pkgSetting.setTimeStamp(scanFileTime); 9554 9555 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 9556 if (nonMutatedPs != null) { 9557 synchronized (mPackages) { 9558 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 9559 } 9560 } 9561 } else { 9562 final int userId = user == null ? 0 : user.getIdentifier(); 9563 // Modify state for the given package setting 9564 commitPackageSettings(pkg, pkgSetting, user, scanFlags, 9565 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/); 9566 if (pkgSetting.getInstantApp(userId)) { 9567 mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId); 9568 } 9569 } 9570 return pkg; 9571 } 9572 9573 /** 9574 * Applies policy to the parsed package based upon the given policy flags. 9575 * Ensures the package is in a good state. 9576 * <p> 9577 * Implementation detail: This method must NOT have any side effect. It would 9578 * ideally be static, but, it requires locks to read system state. 9579 */ 9580 private void applyPolicy(PackageParser.Package pkg, int policyFlags) { 9581 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 9582 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 9583 if (pkg.applicationInfo.isDirectBootAware()) { 9584 // we're direct boot aware; set for all components 9585 for (PackageParser.Service s : pkg.services) { 9586 s.info.encryptionAware = s.info.directBootAware = true; 9587 } 9588 for (PackageParser.Provider p : pkg.providers) { 9589 p.info.encryptionAware = p.info.directBootAware = true; 9590 } 9591 for (PackageParser.Activity a : pkg.activities) { 9592 a.info.encryptionAware = a.info.directBootAware = true; 9593 } 9594 for (PackageParser.Activity r : pkg.receivers) { 9595 r.info.encryptionAware = r.info.directBootAware = true; 9596 } 9597 } 9598 } else { 9599 // Only allow system apps to be flagged as core apps. 9600 pkg.coreApp = false; 9601 // clear flags not applicable to regular apps 9602 pkg.applicationInfo.privateFlags &= 9603 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 9604 pkg.applicationInfo.privateFlags &= 9605 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 9606 } 9607 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 9608 9609 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 9610 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 9611 } 9612 9613 if (!isSystemApp(pkg)) { 9614 // Only system apps can use these features. 9615 pkg.mOriginalPackages = null; 9616 pkg.mRealPackage = null; 9617 pkg.mAdoptPermissions = null; 9618 } 9619 } 9620 9621 /** 9622 * Asserts the parsed package is valid according to the given policy. If the 9623 * package is invalid, for whatever reason, throws {@link PackageManagerException}. 9624 * <p> 9625 * Implementation detail: This method must NOT have any side effects. It would 9626 * ideally be static, but, it requires locks to read system state. 9627 * 9628 * @throws PackageManagerException If the package fails any of the validation checks 9629 */ 9630 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags) 9631 throws PackageManagerException { 9632 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 9633 assertCodePolicy(pkg); 9634 } 9635 9636 if (pkg.applicationInfo.getCodePath() == null || 9637 pkg.applicationInfo.getResourcePath() == null) { 9638 // Bail out. The resource and code paths haven't been set. 9639 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 9640 "Code and resource paths haven't been set correctly"); 9641 } 9642 9643 // Make sure we're not adding any bogus keyset info 9644 KeySetManagerService ksms = mSettings.mKeySetManagerService; 9645 ksms.assertScannedPackageValid(pkg); 9646 9647 synchronized (mPackages) { 9648 // The special "android" package can only be defined once 9649 if (pkg.packageName.equals("android")) { 9650 if (mAndroidApplication != null) { 9651 Slog.w(TAG, "*************************************************"); 9652 Slog.w(TAG, "Core android package being redefined. Skipping."); 9653 Slog.w(TAG, " codePath=" + pkg.codePath); 9654 Slog.w(TAG, "*************************************************"); 9655 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 9656 "Core android package being redefined. Skipping."); 9657 } 9658 } 9659 9660 // A package name must be unique; don't allow duplicates 9661 if (mPackages.containsKey(pkg.packageName)) { 9662 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 9663 "Application package " + pkg.packageName 9664 + " already installed. Skipping duplicate."); 9665 } 9666 9667 if (pkg.applicationInfo.isStaticSharedLibrary()) { 9668 // Static libs have a synthetic package name containing the version 9669 // but we still want the base name to be unique. 9670 if (mPackages.containsKey(pkg.manifestPackageName)) { 9671 throw new PackageManagerException( 9672 "Duplicate static shared lib provider package"); 9673 } 9674 9675 // Static shared libraries should have at least O target SDK 9676 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) { 9677 throw new PackageManagerException( 9678 "Packages declaring static-shared libs must target O SDK or higher"); 9679 } 9680 9681 // Package declaring static a shared lib cannot be instant apps 9682 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 9683 throw new PackageManagerException( 9684 "Packages declaring static-shared libs cannot be instant apps"); 9685 } 9686 9687 // Package declaring static a shared lib cannot be renamed since the package 9688 // name is synthetic and apps can't code around package manager internals. 9689 if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) { 9690 throw new PackageManagerException( 9691 "Packages declaring static-shared libs cannot be renamed"); 9692 } 9693 9694 // Package declaring static a shared lib cannot declare child packages 9695 if (!ArrayUtils.isEmpty(pkg.childPackages)) { 9696 throw new PackageManagerException( 9697 "Packages declaring static-shared libs cannot have child packages"); 9698 } 9699 9700 // Package declaring static a shared lib cannot declare dynamic libs 9701 if (!ArrayUtils.isEmpty(pkg.libraryNames)) { 9702 throw new PackageManagerException( 9703 "Packages declaring static-shared libs cannot declare dynamic libs"); 9704 } 9705 9706 // Package declaring static a shared lib cannot declare shared users 9707 if (pkg.mSharedUserId != null) { 9708 throw new PackageManagerException( 9709 "Packages declaring static-shared libs cannot declare shared users"); 9710 } 9711 9712 // Static shared libs cannot declare activities 9713 if (!pkg.activities.isEmpty()) { 9714 throw new PackageManagerException( 9715 "Static shared libs cannot declare activities"); 9716 } 9717 9718 // Static shared libs cannot declare services 9719 if (!pkg.services.isEmpty()) { 9720 throw new PackageManagerException( 9721 "Static shared libs cannot declare services"); 9722 } 9723 9724 // Static shared libs cannot declare providers 9725 if (!pkg.providers.isEmpty()) { 9726 throw new PackageManagerException( 9727 "Static shared libs cannot declare content providers"); 9728 } 9729 9730 // Static shared libs cannot declare receivers 9731 if (!pkg.receivers.isEmpty()) { 9732 throw new PackageManagerException( 9733 "Static shared libs cannot declare broadcast receivers"); 9734 } 9735 9736 // Static shared libs cannot declare permission groups 9737 if (!pkg.permissionGroups.isEmpty()) { 9738 throw new PackageManagerException( 9739 "Static shared libs cannot declare permission groups"); 9740 } 9741 9742 // Static shared libs cannot declare permissions 9743 if (!pkg.permissions.isEmpty()) { 9744 throw new PackageManagerException( 9745 "Static shared libs cannot declare permissions"); 9746 } 9747 9748 // Static shared libs cannot declare protected broadcasts 9749 if (pkg.protectedBroadcasts != null) { 9750 throw new PackageManagerException( 9751 "Static shared libs cannot declare protected broadcasts"); 9752 } 9753 9754 // Static shared libs cannot be overlay targets 9755 if (pkg.mOverlayTarget != null) { 9756 throw new PackageManagerException( 9757 "Static shared libs cannot be overlay targets"); 9758 } 9759 9760 // The version codes must be ordered as lib versions 9761 int minVersionCode = Integer.MIN_VALUE; 9762 int maxVersionCode = Integer.MAX_VALUE; 9763 9764 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get( 9765 pkg.staticSharedLibName); 9766 if (versionedLib != null) { 9767 final int versionCount = versionedLib.size(); 9768 for (int i = 0; i < versionCount; i++) { 9769 SharedLibraryInfo libInfo = versionedLib.valueAt(i).info; 9770 // TODO: We will change version code to long, so in the new API it is long 9771 final int libVersionCode = (int) libInfo.getDeclaringPackage() 9772 .getVersionCode(); 9773 if (libInfo.getVersion() < pkg.staticSharedLibVersion) { 9774 minVersionCode = Math.max(minVersionCode, libVersionCode + 1); 9775 } else if (libInfo.getVersion() > pkg.staticSharedLibVersion) { 9776 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1); 9777 } else { 9778 minVersionCode = maxVersionCode = libVersionCode; 9779 break; 9780 } 9781 } 9782 } 9783 if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) { 9784 throw new PackageManagerException("Static shared" 9785 + " lib version codes must be ordered as lib versions"); 9786 } 9787 } 9788 9789 // Only privileged apps and updated privileged apps can add child packages. 9790 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 9791 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 9792 throw new PackageManagerException("Only privileged apps can add child " 9793 + "packages. Ignoring package " + pkg.packageName); 9794 } 9795 final int childCount = pkg.childPackages.size(); 9796 for (int i = 0; i < childCount; i++) { 9797 PackageParser.Package childPkg = pkg.childPackages.get(i); 9798 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 9799 childPkg.packageName)) { 9800 throw new PackageManagerException("Can't override child of " 9801 + "another disabled app. Ignoring package " + pkg.packageName); 9802 } 9803 } 9804 } 9805 9806 // If we're only installing presumed-existing packages, require that the 9807 // scanned APK is both already known and at the path previously established 9808 // for it. Previously unknown packages we pick up normally, but if we have an 9809 // a priori expectation about this package's install presence, enforce it. 9810 // With a singular exception for new system packages. When an OTA contains 9811 // a new system package, we allow the codepath to change from a system location 9812 // to the user-installed location. If we don't allow this change, any newer, 9813 // user-installed version of the application will be ignored. 9814 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 9815 if (mExpectingBetter.containsKey(pkg.packageName)) { 9816 logCriticalInfo(Log.WARN, 9817 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 9818 } else { 9819 PackageSetting known = mSettings.getPackageLPr(pkg.packageName); 9820 if (known != null) { 9821 if (DEBUG_PACKAGE_SCANNING) { 9822 Log.d(TAG, "Examining " + pkg.codePath 9823 + " and requiring known paths " + known.codePathString 9824 + " & " + known.resourcePathString); 9825 } 9826 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 9827 || !pkg.applicationInfo.getResourcePath().equals( 9828 known.resourcePathString)) { 9829 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 9830 "Application package " + pkg.packageName 9831 + " found at " + pkg.applicationInfo.getCodePath() 9832 + " but expected at " + known.codePathString 9833 + "; ignoring."); 9834 } 9835 } 9836 } 9837 } 9838 9839 // Verify that this new package doesn't have any content providers 9840 // that conflict with existing packages. Only do this if the 9841 // package isn't already installed, since we don't want to break 9842 // things that are installed. 9843 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 9844 final int N = pkg.providers.size(); 9845 int i; 9846 for (i=0; i<N; i++) { 9847 PackageParser.Provider p = pkg.providers.get(i); 9848 if (p.info.authority != null) { 9849 String names[] = p.info.authority.split(";"); 9850 for (int j = 0; j < names.length; j++) { 9851 if (mProvidersByAuthority.containsKey(names[j])) { 9852 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 9853 final String otherPackageName = 9854 ((other != null && other.getComponentName() != null) ? 9855 other.getComponentName().getPackageName() : "?"); 9856 throw new PackageManagerException( 9857 INSTALL_FAILED_CONFLICTING_PROVIDER, 9858 "Can't install because provider name " + names[j] 9859 + " (in package " + pkg.applicationInfo.packageName 9860 + ") is already used by " + otherPackageName); 9861 } 9862 } 9863 } 9864 } 9865 } 9866 } 9867 } 9868 9869 private boolean addSharedLibraryLPw(String path, String apk, String name, int version, 9870 int type, String declaringPackageName, int declaringVersionCode) { 9871 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 9872 if (versionedLib == null) { 9873 versionedLib = new SparseArray<>(); 9874 mSharedLibraries.put(name, versionedLib); 9875 if (type == SharedLibraryInfo.TYPE_STATIC) { 9876 mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib); 9877 } 9878 } else if (versionedLib.indexOfKey(version) >= 0) { 9879 return false; 9880 } 9881 SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name, 9882 version, type, declaringPackageName, declaringVersionCode); 9883 versionedLib.put(version, libEntry); 9884 return true; 9885 } 9886 9887 private boolean removeSharedLibraryLPw(String name, int version) { 9888 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name); 9889 if (versionedLib == null) { 9890 return false; 9891 } 9892 final int libIdx = versionedLib.indexOfKey(version); 9893 if (libIdx < 0) { 9894 return false; 9895 } 9896 SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx); 9897 versionedLib.remove(version); 9898 if (versionedLib.size() <= 0) { 9899 mSharedLibraries.remove(name); 9900 if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) { 9901 mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage() 9902 .getPackageName()); 9903 } 9904 } 9905 return true; 9906 } 9907 9908 /** 9909 * Adds a scanned package to the system. When this method is finished, the package will 9910 * be available for query, resolution, etc... 9911 */ 9912 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting, 9913 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException { 9914 final String pkgName = pkg.packageName; 9915 if (mCustomResolverComponentName != null && 9916 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 9917 setUpCustomResolverActivity(pkg); 9918 } 9919 9920 if (pkg.packageName.equals("android")) { 9921 synchronized (mPackages) { 9922 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 9923 // Set up information for our fall-back user intent resolution activity. 9924 mPlatformPackage = pkg; 9925 pkg.mVersionCode = mSdkVersion; 9926 mAndroidApplication = pkg.applicationInfo; 9927 if (!mResolverReplaced) { 9928 mResolveActivity.applicationInfo = mAndroidApplication; 9929 mResolveActivity.name = ResolverActivity.class.getName(); 9930 mResolveActivity.packageName = mAndroidApplication.packageName; 9931 mResolveActivity.processName = "system:ui"; 9932 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9933 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 9934 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 9935 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 9936 mResolveActivity.exported = true; 9937 mResolveActivity.enabled = true; 9938 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 9939 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 9940 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 9941 | ActivityInfo.CONFIG_SCREEN_LAYOUT 9942 | ActivityInfo.CONFIG_ORIENTATION 9943 | ActivityInfo.CONFIG_KEYBOARD 9944 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 9945 mResolveInfo.activityInfo = mResolveActivity; 9946 mResolveInfo.priority = 0; 9947 mResolveInfo.preferredOrder = 0; 9948 mResolveInfo.match = 0; 9949 mResolveComponentName = new ComponentName( 9950 mAndroidApplication.packageName, mResolveActivity.name); 9951 } 9952 } 9953 } 9954 } 9955 9956 ArrayList<PackageParser.Package> clientLibPkgs = null; 9957 // writer 9958 synchronized (mPackages) { 9959 boolean hasStaticSharedLibs = false; 9960 9961 // Any app can add new static shared libraries 9962 if (pkg.staticSharedLibName != null) { 9963 // Static shared libs don't allow renaming as they have synthetic package 9964 // names to allow install of multiple versions, so use name from manifest. 9965 if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName, 9966 pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC, 9967 pkg.manifestPackageName, pkg.mVersionCode)) { 9968 hasStaticSharedLibs = true; 9969 } else { 9970 Slog.w(TAG, "Package " + pkg.packageName + " library " 9971 + pkg.staticSharedLibName + " already exists; skipping"); 9972 } 9973 // Static shared libs cannot be updated once installed since they 9974 // use synthetic package name which includes the version code, so 9975 // not need to update other packages's shared lib dependencies. 9976 } 9977 9978 if (!hasStaticSharedLibs 9979 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9980 // Only system apps can add new dynamic shared libraries. 9981 if (pkg.libraryNames != null) { 9982 for (int i = 0; i < pkg.libraryNames.size(); i++) { 9983 String name = pkg.libraryNames.get(i); 9984 boolean allowed = false; 9985 if (pkg.isUpdatedSystemApp()) { 9986 // New library entries can only be added through the 9987 // system image. This is important to get rid of a lot 9988 // of nasty edge cases: for example if we allowed a non- 9989 // system update of the app to add a library, then uninstalling 9990 // the update would make the library go away, and assumptions 9991 // we made such as through app install filtering would now 9992 // have allowed apps on the device which aren't compatible 9993 // with it. Better to just have the restriction here, be 9994 // conservative, and create many fewer cases that can negatively 9995 // impact the user experience. 9996 final PackageSetting sysPs = mSettings 9997 .getDisabledSystemPkgLPr(pkg.packageName); 9998 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 9999 for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) { 10000 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 10001 allowed = true; 10002 break; 10003 } 10004 } 10005 } 10006 } else { 10007 allowed = true; 10008 } 10009 if (allowed) { 10010 if (!addSharedLibraryLPw(null, pkg.packageName, name, 10011 SharedLibraryInfo.VERSION_UNDEFINED, 10012 SharedLibraryInfo.TYPE_DYNAMIC, 10013 pkg.packageName, pkg.mVersionCode)) { 10014 Slog.w(TAG, "Package " + pkg.packageName + " library " 10015 + name + " already exists; skipping"); 10016 } 10017 } else { 10018 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 10019 + name + " that is not declared on system image; skipping"); 10020 } 10021 } 10022 10023 if ((scanFlags & SCAN_BOOTING) == 0) { 10024 // If we are not booting, we need to update any applications 10025 // that are clients of our shared library. If we are booting, 10026 // this will all be done once the scan is complete. 10027 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 10028 } 10029 } 10030 } 10031 } 10032 10033 if ((scanFlags & SCAN_BOOTING) != 0) { 10034 // No apps can run during boot scan, so they don't need to be frozen 10035 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 10036 // Caller asked to not kill app, so it's probably not frozen 10037 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 10038 // Caller asked us to ignore frozen check for some reason; they 10039 // probably didn't know the package name 10040 } else { 10041 // We're doing major surgery on this package, so it better be frozen 10042 // right now to keep it from launching 10043 checkPackageFrozen(pkgName); 10044 } 10045 10046 // Also need to kill any apps that are dependent on the library. 10047 if (clientLibPkgs != null) { 10048 for (int i=0; i<clientLibPkgs.size(); i++) { 10049 PackageParser.Package clientPkg = clientLibPkgs.get(i); 10050 killApplication(clientPkg.applicationInfo.packageName, 10051 clientPkg.applicationInfo.uid, "update lib"); 10052 } 10053 } 10054 10055 // writer 10056 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 10057 10058 synchronized (mPackages) { 10059 // We don't expect installation to fail beyond this point 10060 10061 // Add the new setting to mSettings 10062 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 10063 // Add the new setting to mPackages 10064 mPackages.put(pkg.applicationInfo.packageName, pkg); 10065 // Make sure we don't accidentally delete its data. 10066 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 10067 while (iter.hasNext()) { 10068 PackageCleanItem item = iter.next(); 10069 if (pkgName.equals(item.packageName)) { 10070 iter.remove(); 10071 } 10072 } 10073 10074 // Add the package's KeySets to the global KeySetManagerService 10075 KeySetManagerService ksms = mSettings.mKeySetManagerService; 10076 ksms.addScannedPackageLPw(pkg); 10077 10078 int N = pkg.providers.size(); 10079 StringBuilder r = null; 10080 int i; 10081 for (i=0; i<N; i++) { 10082 PackageParser.Provider p = pkg.providers.get(i); 10083 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 10084 p.info.processName); 10085 mProviders.addProvider(p); 10086 p.syncable = p.info.isSyncable; 10087 if (p.info.authority != null) { 10088 String names[] = p.info.authority.split(";"); 10089 p.info.authority = null; 10090 for (int j = 0; j < names.length; j++) { 10091 if (j == 1 && p.syncable) { 10092 // We only want the first authority for a provider to possibly be 10093 // syncable, so if we already added this provider using a different 10094 // authority clear the syncable flag. We copy the provider before 10095 // changing it because the mProviders object contains a reference 10096 // to a provider that we don't want to change. 10097 // Only do this for the second authority since the resulting provider 10098 // object can be the same for all future authorities for this provider. 10099 p = new PackageParser.Provider(p); 10100 p.syncable = false; 10101 } 10102 if (!mProvidersByAuthority.containsKey(names[j])) { 10103 mProvidersByAuthority.put(names[j], p); 10104 if (p.info.authority == null) { 10105 p.info.authority = names[j]; 10106 } else { 10107 p.info.authority = p.info.authority + ";" + names[j]; 10108 } 10109 if (DEBUG_PACKAGE_SCANNING) { 10110 if (chatty) 10111 Log.d(TAG, "Registered content provider: " + names[j] 10112 + ", className = " + p.info.name + ", isSyncable = " 10113 + p.info.isSyncable); 10114 } 10115 } else { 10116 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 10117 Slog.w(TAG, "Skipping provider name " + names[j] + 10118 " (in package " + pkg.applicationInfo.packageName + 10119 "): name already used by " 10120 + ((other != null && other.getComponentName() != null) 10121 ? other.getComponentName().getPackageName() : "?")); 10122 } 10123 } 10124 } 10125 if (chatty) { 10126 if (r == null) { 10127 r = new StringBuilder(256); 10128 } else { 10129 r.append(' '); 10130 } 10131 r.append(p.info.name); 10132 } 10133 } 10134 if (r != null) { 10135 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 10136 } 10137 10138 N = pkg.services.size(); 10139 r = null; 10140 for (i=0; i<N; i++) { 10141 PackageParser.Service s = pkg.services.get(i); 10142 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 10143 s.info.processName); 10144 mServices.addService(s); 10145 if (chatty) { 10146 if (r == null) { 10147 r = new StringBuilder(256); 10148 } else { 10149 r.append(' '); 10150 } 10151 r.append(s.info.name); 10152 } 10153 } 10154 if (r != null) { 10155 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 10156 } 10157 10158 N = pkg.receivers.size(); 10159 r = null; 10160 for (i=0; i<N; i++) { 10161 PackageParser.Activity a = pkg.receivers.get(i); 10162 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 10163 a.info.processName); 10164 mReceivers.addActivity(a, "receiver"); 10165 if (chatty) { 10166 if (r == null) { 10167 r = new StringBuilder(256); 10168 } else { 10169 r.append(' '); 10170 } 10171 r.append(a.info.name); 10172 } 10173 } 10174 if (r != null) { 10175 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 10176 } 10177 10178 N = pkg.activities.size(); 10179 r = null; 10180 for (i=0; i<N; i++) { 10181 PackageParser.Activity a = pkg.activities.get(i); 10182 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 10183 a.info.processName); 10184 mActivities.addActivity(a, "activity"); 10185 if (chatty) { 10186 if (r == null) { 10187 r = new StringBuilder(256); 10188 } else { 10189 r.append(' '); 10190 } 10191 r.append(a.info.name); 10192 } 10193 } 10194 if (r != null) { 10195 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 10196 } 10197 10198 N = pkg.permissionGroups.size(); 10199 r = null; 10200 for (i=0; i<N; i++) { 10201 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 10202 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 10203 final String curPackageName = cur == null ? null : cur.info.packageName; 10204 // Dont allow ephemeral apps to define new permission groups. 10205 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 10206 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 10207 + pg.info.packageName 10208 + " ignored: instant apps cannot define new permission groups."); 10209 continue; 10210 } 10211 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 10212 if (cur == null || isPackageUpdate) { 10213 mPermissionGroups.put(pg.info.name, pg); 10214 if (chatty) { 10215 if (r == null) { 10216 r = new StringBuilder(256); 10217 } else { 10218 r.append(' '); 10219 } 10220 if (isPackageUpdate) { 10221 r.append("UPD:"); 10222 } 10223 r.append(pg.info.name); 10224 } 10225 } else { 10226 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 10227 + pg.info.packageName + " ignored: original from " 10228 + cur.info.packageName); 10229 if (chatty) { 10230 if (r == null) { 10231 r = new StringBuilder(256); 10232 } else { 10233 r.append(' '); 10234 } 10235 r.append("DUP:"); 10236 r.append(pg.info.name); 10237 } 10238 } 10239 } 10240 if (r != null) { 10241 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 10242 } 10243 10244 N = pkg.permissions.size(); 10245 r = null; 10246 for (i=0; i<N; i++) { 10247 PackageParser.Permission p = pkg.permissions.get(i); 10248 10249 // Dont allow ephemeral apps to define new permissions. 10250 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 10251 Slog.w(TAG, "Permission " + p.info.name + " from package " 10252 + p.info.packageName 10253 + " ignored: instant apps cannot define new permissions."); 10254 continue; 10255 } 10256 10257 // Assume by default that we did not install this permission into the system. 10258 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 10259 10260 // Now that permission groups have a special meaning, we ignore permission 10261 // groups for legacy apps to prevent unexpected behavior. In particular, 10262 // permissions for one app being granted to someone just becase they happen 10263 // to be in a group defined by another app (before this had no implications). 10264 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 10265 p.group = mPermissionGroups.get(p.info.group); 10266 // Warn for a permission in an unknown group. 10267 if (p.info.group != null && p.group == null) { 10268 Slog.w(TAG, "Permission " + p.info.name + " from package " 10269 + p.info.packageName + " in an unknown group " + p.info.group); 10270 } 10271 } 10272 10273 ArrayMap<String, BasePermission> permissionMap = 10274 p.tree ? mSettings.mPermissionTrees 10275 : mSettings.mPermissions; 10276 BasePermission bp = permissionMap.get(p.info.name); 10277 10278 // Allow system apps to redefine non-system permissions 10279 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 10280 final boolean currentOwnerIsSystem = (bp.perm != null 10281 && isSystemApp(bp.perm.owner)); 10282 if (isSystemApp(p.owner)) { 10283 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 10284 // It's a built-in permission and no owner, take ownership now 10285 bp.packageSetting = pkgSetting; 10286 bp.perm = p; 10287 bp.uid = pkg.applicationInfo.uid; 10288 bp.sourcePackage = p.info.packageName; 10289 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 10290 } else if (!currentOwnerIsSystem) { 10291 String msg = "New decl " + p.owner + " of permission " 10292 + p.info.name + " is system; overriding " + bp.sourcePackage; 10293 reportSettingsProblem(Log.WARN, msg); 10294 bp = null; 10295 } 10296 } 10297 } 10298 10299 if (bp == null) { 10300 bp = new BasePermission(p.info.name, p.info.packageName, 10301 BasePermission.TYPE_NORMAL); 10302 permissionMap.put(p.info.name, bp); 10303 } 10304 10305 if (bp.perm == null) { 10306 if (bp.sourcePackage == null 10307 || bp.sourcePackage.equals(p.info.packageName)) { 10308 BasePermission tree = findPermissionTreeLP(p.info.name); 10309 if (tree == null 10310 || tree.sourcePackage.equals(p.info.packageName)) { 10311 bp.packageSetting = pkgSetting; 10312 bp.perm = p; 10313 bp.uid = pkg.applicationInfo.uid; 10314 bp.sourcePackage = p.info.packageName; 10315 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 10316 if (chatty) { 10317 if (r == null) { 10318 r = new StringBuilder(256); 10319 } else { 10320 r.append(' '); 10321 } 10322 r.append(p.info.name); 10323 } 10324 } else { 10325 Slog.w(TAG, "Permission " + p.info.name + " from package " 10326 + p.info.packageName + " ignored: base tree " 10327 + tree.name + " is from package " 10328 + tree.sourcePackage); 10329 } 10330 } else { 10331 Slog.w(TAG, "Permission " + p.info.name + " from package " 10332 + p.info.packageName + " ignored: original from " 10333 + bp.sourcePackage); 10334 } 10335 } else if (chatty) { 10336 if (r == null) { 10337 r = new StringBuilder(256); 10338 } else { 10339 r.append(' '); 10340 } 10341 r.append("DUP:"); 10342 r.append(p.info.name); 10343 } 10344 if (bp.perm == p) { 10345 bp.protectionLevel = p.info.protectionLevel; 10346 } 10347 } 10348 10349 if (r != null) { 10350 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 10351 } 10352 10353 N = pkg.instrumentation.size(); 10354 r = null; 10355 for (i=0; i<N; i++) { 10356 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 10357 a.info.packageName = pkg.applicationInfo.packageName; 10358 a.info.sourceDir = pkg.applicationInfo.sourceDir; 10359 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 10360 a.info.splitNames = pkg.splitNames; 10361 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 10362 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 10363 a.info.splitDependencies = pkg.applicationInfo.splitDependencies; 10364 a.info.dataDir = pkg.applicationInfo.dataDir; 10365 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 10366 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 10367 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 10368 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 10369 mInstrumentation.put(a.getComponentName(), a); 10370 if (chatty) { 10371 if (r == null) { 10372 r = new StringBuilder(256); 10373 } else { 10374 r.append(' '); 10375 } 10376 r.append(a.info.name); 10377 } 10378 } 10379 if (r != null) { 10380 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 10381 } 10382 10383 if (pkg.protectedBroadcasts != null) { 10384 N = pkg.protectedBroadcasts.size(); 10385 for (i=0; i<N; i++) { 10386 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 10387 } 10388 } 10389 } 10390 10391 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10392 } 10393 10394 /** 10395 * Derive the ABI of a non-system package located at {@code scanFile}. This information 10396 * is derived purely on the basis of the contents of {@code scanFile} and 10397 * {@code cpuAbiOverride}. 10398 * 10399 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 10400 */ 10401 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile, 10402 String cpuAbiOverride, boolean extractLibs, 10403 File appLib32InstallDir) 10404 throws PackageManagerException { 10405 // Give ourselves some initial paths; we'll come back for another 10406 // pass once we've determined ABI below. 10407 setNativeLibraryPaths(pkg, appLib32InstallDir); 10408 10409 // We would never need to extract libs for forward-locked and external packages, 10410 // since the container service will do it for us. We shouldn't attempt to 10411 // extract libs from system app when it was not updated. 10412 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 10413 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 10414 extractLibs = false; 10415 } 10416 10417 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 10418 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 10419 10420 NativeLibraryHelper.Handle handle = null; 10421 try { 10422 handle = NativeLibraryHelper.Handle.create(pkg); 10423 // TODO(multiArch): This can be null for apps that didn't go through the 10424 // usual installation process. We can calculate it again, like we 10425 // do during install time. 10426 // 10427 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 10428 // unnecessary. 10429 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 10430 10431 // Null out the abis so that they can be recalculated. 10432 pkg.applicationInfo.primaryCpuAbi = null; 10433 pkg.applicationInfo.secondaryCpuAbi = null; 10434 if (isMultiArch(pkg.applicationInfo)) { 10435 // Warn if we've set an abiOverride for multi-lib packages.. 10436 // By definition, we need to copy both 32 and 64 bit libraries for 10437 // such packages. 10438 if (pkg.cpuAbiOverride != null 10439 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 10440 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 10441 } 10442 10443 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 10444 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 10445 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 10446 if (extractLibs) { 10447 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10448 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10449 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 10450 useIsaSpecificSubdirs); 10451 } else { 10452 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10453 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 10454 } 10455 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10456 } 10457 10458 maybeThrowExceptionForMultiArchCopy( 10459 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 10460 10461 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 10462 if (extractLibs) { 10463 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10464 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10465 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 10466 useIsaSpecificSubdirs); 10467 } else { 10468 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10469 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 10470 } 10471 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10472 } 10473 10474 maybeThrowExceptionForMultiArchCopy( 10475 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 10476 10477 if (abi64 >= 0) { 10478 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 10479 } 10480 10481 if (abi32 >= 0) { 10482 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 10483 if (abi64 >= 0) { 10484 if (pkg.use32bitAbi) { 10485 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 10486 pkg.applicationInfo.primaryCpuAbi = abi; 10487 } else { 10488 pkg.applicationInfo.secondaryCpuAbi = abi; 10489 } 10490 } else { 10491 pkg.applicationInfo.primaryCpuAbi = abi; 10492 } 10493 } 10494 10495 } else { 10496 String[] abiList = (cpuAbiOverride != null) ? 10497 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 10498 10499 // Enable gross and lame hacks for apps that are built with old 10500 // SDK tools. We must scan their APKs for renderscript bitcode and 10501 // not launch them if it's present. Don't bother checking on devices 10502 // that don't have 64 bit support. 10503 boolean needsRenderScriptOverride = false; 10504 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 10505 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 10506 abiList = Build.SUPPORTED_32_BIT_ABIS; 10507 needsRenderScriptOverride = true; 10508 } 10509 10510 final int copyRet; 10511 if (extractLibs) { 10512 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 10513 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 10514 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 10515 } else { 10516 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 10517 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 10518 } 10519 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10520 10521 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 10522 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 10523 "Error unpackaging native libs for app, errorCode=" + copyRet); 10524 } 10525 10526 if (copyRet >= 0) { 10527 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 10528 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 10529 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 10530 } else if (needsRenderScriptOverride) { 10531 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 10532 } 10533 } 10534 } catch (IOException ioe) { 10535 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 10536 } finally { 10537 IoUtils.closeQuietly(handle); 10538 } 10539 10540 // Now that we've calculated the ABIs and determined if it's an internal app, 10541 // we will go ahead and populate the nativeLibraryPath. 10542 setNativeLibraryPaths(pkg, appLib32InstallDir); 10543 } 10544 10545 /** 10546 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 10547 * i.e, so that all packages can be run inside a single process if required. 10548 * 10549 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 10550 * this function will either try and make the ABI for all packages in {@code packagesForUser} 10551 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 10552 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 10553 * updating a package that belongs to a shared user. 10554 * 10555 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 10556 * adds unnecessary complexity. 10557 */ 10558 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 10559 PackageParser.Package scannedPackage) { 10560 String requiredInstructionSet = null; 10561 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 10562 requiredInstructionSet = VMRuntime.getInstructionSet( 10563 scannedPackage.applicationInfo.primaryCpuAbi); 10564 } 10565 10566 PackageSetting requirer = null; 10567 for (PackageSetting ps : packagesForUser) { 10568 // If packagesForUser contains scannedPackage, we skip it. This will happen 10569 // when scannedPackage is an update of an existing package. Without this check, 10570 // we will never be able to change the ABI of any package belonging to a shared 10571 // user, even if it's compatible with other packages. 10572 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 10573 if (ps.primaryCpuAbiString == null) { 10574 continue; 10575 } 10576 10577 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 10578 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 10579 // We have a mismatch between instruction sets (say arm vs arm64) warn about 10580 // this but there's not much we can do. 10581 String errorMessage = "Instruction set mismatch, " 10582 + ((requirer == null) ? "[caller]" : requirer) 10583 + " requires " + requiredInstructionSet + " whereas " + ps 10584 + " requires " + instructionSet; 10585 Slog.w(TAG, errorMessage); 10586 } 10587 10588 if (requiredInstructionSet == null) { 10589 requiredInstructionSet = instructionSet; 10590 requirer = ps; 10591 } 10592 } 10593 } 10594 10595 if (requiredInstructionSet != null) { 10596 String adjustedAbi; 10597 if (requirer != null) { 10598 // requirer != null implies that either scannedPackage was null or that scannedPackage 10599 // did not require an ABI, in which case we have to adjust scannedPackage to match 10600 // the ABI of the set (which is the same as requirer's ABI) 10601 adjustedAbi = requirer.primaryCpuAbiString; 10602 if (scannedPackage != null) { 10603 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 10604 } 10605 } else { 10606 // requirer == null implies that we're updating all ABIs in the set to 10607 // match scannedPackage. 10608 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 10609 } 10610 10611 for (PackageSetting ps : packagesForUser) { 10612 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 10613 if (ps.primaryCpuAbiString != null) { 10614 continue; 10615 } 10616 10617 ps.primaryCpuAbiString = adjustedAbi; 10618 if (ps.pkg != null && ps.pkg.applicationInfo != null && 10619 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 10620 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 10621 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 10622 + " (requirer=" 10623 + (requirer != null ? requirer.pkg : "null") 10624 + ", scannedPackage=" 10625 + (scannedPackage != null ? scannedPackage : "null") 10626 + ")"); 10627 try { 10628 mInstaller.rmdex(ps.codePathString, 10629 getDexCodeInstructionSet(getPreferredInstructionSet())); 10630 } catch (InstallerException ignored) { 10631 } 10632 } 10633 } 10634 } 10635 } 10636 } 10637 10638 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 10639 synchronized (mPackages) { 10640 mResolverReplaced = true; 10641 // Set up information for custom user intent resolution activity. 10642 mResolveActivity.applicationInfo = pkg.applicationInfo; 10643 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 10644 mResolveActivity.packageName = pkg.applicationInfo.packageName; 10645 mResolveActivity.processName = pkg.applicationInfo.packageName; 10646 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 10647 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 10648 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 10649 mResolveActivity.theme = 0; 10650 mResolveActivity.exported = true; 10651 mResolveActivity.enabled = true; 10652 mResolveInfo.activityInfo = mResolveActivity; 10653 mResolveInfo.priority = 0; 10654 mResolveInfo.preferredOrder = 0; 10655 mResolveInfo.match = 0; 10656 mResolveComponentName = mCustomResolverComponentName; 10657 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 10658 mResolveComponentName); 10659 } 10660 } 10661 10662 private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) { 10663 if (installerActivity == null) { 10664 if (DEBUG_EPHEMERAL) { 10665 Slog.d(TAG, "Clear ephemeral installer activity"); 10666 } 10667 mInstantAppInstallerActivity = null; 10668 return; 10669 } 10670 10671 if (DEBUG_EPHEMERAL) { 10672 Slog.d(TAG, "Set ephemeral installer activity: " 10673 + installerActivity.getComponentName()); 10674 } 10675 // Set up information for ephemeral installer activity 10676 mInstantAppInstallerActivity = installerActivity; 10677 mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 10678 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 10679 mInstantAppInstallerActivity.exported = true; 10680 mInstantAppInstallerActivity.enabled = true; 10681 mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity; 10682 mInstantAppInstallerInfo.priority = 0; 10683 mInstantAppInstallerInfo.preferredOrder = 1; 10684 mInstantAppInstallerInfo.isDefault = true; 10685 mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 10686 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 10687 } 10688 10689 private static String calculateBundledApkRoot(final String codePathString) { 10690 final File codePath = new File(codePathString); 10691 final File codeRoot; 10692 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 10693 codeRoot = Environment.getRootDirectory(); 10694 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 10695 codeRoot = Environment.getOemDirectory(); 10696 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 10697 codeRoot = Environment.getVendorDirectory(); 10698 } else { 10699 // Unrecognized code path; take its top real segment as the apk root: 10700 // e.g. /something/app/blah.apk => /something 10701 try { 10702 File f = codePath.getCanonicalFile(); 10703 File parent = f.getParentFile(); // non-null because codePath is a file 10704 File tmp; 10705 while ((tmp = parent.getParentFile()) != null) { 10706 f = parent; 10707 parent = tmp; 10708 } 10709 codeRoot = f; 10710 Slog.w(TAG, "Unrecognized code path " 10711 + codePath + " - using " + codeRoot); 10712 } catch (IOException e) { 10713 // Can't canonicalize the code path -- shenanigans? 10714 Slog.w(TAG, "Can't canonicalize code path " + codePath); 10715 return Environment.getRootDirectory().getPath(); 10716 } 10717 } 10718 return codeRoot.getPath(); 10719 } 10720 10721 /** 10722 * Derive and set the location of native libraries for the given package, 10723 * which varies depending on where and how the package was installed. 10724 */ 10725 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) { 10726 final ApplicationInfo info = pkg.applicationInfo; 10727 final String codePath = pkg.codePath; 10728 final File codeFile = new File(codePath); 10729 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 10730 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 10731 10732 info.nativeLibraryRootDir = null; 10733 info.nativeLibraryRootRequiresIsa = false; 10734 info.nativeLibraryDir = null; 10735 info.secondaryNativeLibraryDir = null; 10736 10737 if (isApkFile(codeFile)) { 10738 // Monolithic install 10739 if (bundledApp) { 10740 // If "/system/lib64/apkname" exists, assume that is the per-package 10741 // native library directory to use; otherwise use "/system/lib/apkname". 10742 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 10743 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 10744 getPrimaryInstructionSet(info)); 10745 10746 // This is a bundled system app so choose the path based on the ABI. 10747 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 10748 // is just the default path. 10749 final String apkName = deriveCodePathName(codePath); 10750 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 10751 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 10752 apkName).getAbsolutePath(); 10753 10754 if (info.secondaryCpuAbi != null) { 10755 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 10756 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 10757 secondaryLibDir, apkName).getAbsolutePath(); 10758 } 10759 } else if (asecApp) { 10760 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 10761 .getAbsolutePath(); 10762 } else { 10763 final String apkName = deriveCodePathName(codePath); 10764 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName) 10765 .getAbsolutePath(); 10766 } 10767 10768 info.nativeLibraryRootRequiresIsa = false; 10769 info.nativeLibraryDir = info.nativeLibraryRootDir; 10770 } else { 10771 // Cluster install 10772 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 10773 info.nativeLibraryRootRequiresIsa = true; 10774 10775 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 10776 getPrimaryInstructionSet(info)).getAbsolutePath(); 10777 10778 if (info.secondaryCpuAbi != null) { 10779 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 10780 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 10781 } 10782 } 10783 } 10784 10785 /** 10786 * Calculate the abis and roots for a bundled app. These can uniquely 10787 * be determined from the contents of the system partition, i.e whether 10788 * it contains 64 or 32 bit shared libraries etc. We do not validate any 10789 * of this information, and instead assume that the system was built 10790 * sensibly. 10791 */ 10792 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg, 10793 PackageSetting pkgSetting) { 10794 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 10795 10796 // If "/system/lib64/apkname" exists, assume that is the per-package 10797 // native library directory to use; otherwise use "/system/lib/apkname". 10798 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 10799 setBundledAppAbi(pkg, apkRoot, apkName); 10800 // pkgSetting might be null during rescan following uninstall of updates 10801 // to a bundled app, so accommodate that possibility. The settings in 10802 // that case will be established later from the parsed package. 10803 // 10804 // If the settings aren't null, sync them up with what we've just derived. 10805 // note that apkRoot isn't stored in the package settings. 10806 if (pkgSetting != null) { 10807 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 10808 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 10809 } 10810 } 10811 10812 /** 10813 * Deduces the ABI of a bundled app and sets the relevant fields on the 10814 * parsed pkg object. 10815 * 10816 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 10817 * under which system libraries are installed. 10818 * @param apkName the name of the installed package. 10819 */ 10820 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 10821 final File codeFile = new File(pkg.codePath); 10822 10823 final boolean has64BitLibs; 10824 final boolean has32BitLibs; 10825 if (isApkFile(codeFile)) { 10826 // Monolithic install 10827 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 10828 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 10829 } else { 10830 // Cluster install 10831 final File rootDir = new File(codeFile, LIB_DIR_NAME); 10832 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 10833 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 10834 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 10835 has64BitLibs = (new File(rootDir, isa)).exists(); 10836 } else { 10837 has64BitLibs = false; 10838 } 10839 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 10840 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 10841 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 10842 has32BitLibs = (new File(rootDir, isa)).exists(); 10843 } else { 10844 has32BitLibs = false; 10845 } 10846 } 10847 10848 if (has64BitLibs && !has32BitLibs) { 10849 // The package has 64 bit libs, but not 32 bit libs. Its primary 10850 // ABI should be 64 bit. We can safely assume here that the bundled 10851 // native libraries correspond to the most preferred ABI in the list. 10852 10853 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10854 pkg.applicationInfo.secondaryCpuAbi = null; 10855 } else if (has32BitLibs && !has64BitLibs) { 10856 // The package has 32 bit libs but not 64 bit libs. Its primary 10857 // ABI should be 32 bit. 10858 10859 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10860 pkg.applicationInfo.secondaryCpuAbi = null; 10861 } else if (has32BitLibs && has64BitLibs) { 10862 // The application has both 64 and 32 bit bundled libraries. We check 10863 // here that the app declares multiArch support, and warn if it doesn't. 10864 // 10865 // We will be lenient here and record both ABIs. The primary will be the 10866 // ABI that's higher on the list, i.e, a device that's configured to prefer 10867 // 64 bit apps will see a 64 bit primary ABI, 10868 10869 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 10870 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 10871 } 10872 10873 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 10874 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10875 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10876 } else { 10877 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10878 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10879 } 10880 } else { 10881 pkg.applicationInfo.primaryCpuAbi = null; 10882 pkg.applicationInfo.secondaryCpuAbi = null; 10883 } 10884 } 10885 10886 private void killApplication(String pkgName, int appId, String reason) { 10887 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 10888 } 10889 10890 private void killApplication(String pkgName, int appId, int userId, String reason) { 10891 // Request the ActivityManager to kill the process(only for existing packages) 10892 // so that we do not end up in a confused state while the user is still using the older 10893 // version of the application while the new one gets installed. 10894 final long token = Binder.clearCallingIdentity(); 10895 try { 10896 IActivityManager am = ActivityManager.getService(); 10897 if (am != null) { 10898 try { 10899 am.killApplication(pkgName, appId, userId, reason); 10900 } catch (RemoteException e) { 10901 } 10902 } 10903 } finally { 10904 Binder.restoreCallingIdentity(token); 10905 } 10906 } 10907 10908 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 10909 // Remove the parent package setting 10910 PackageSetting ps = (PackageSetting) pkg.mExtras; 10911 if (ps != null) { 10912 removePackageLI(ps, chatty); 10913 } 10914 // Remove the child package setting 10915 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10916 for (int i = 0; i < childCount; i++) { 10917 PackageParser.Package childPkg = pkg.childPackages.get(i); 10918 ps = (PackageSetting) childPkg.mExtras; 10919 if (ps != null) { 10920 removePackageLI(ps, chatty); 10921 } 10922 } 10923 } 10924 10925 void removePackageLI(PackageSetting ps, boolean chatty) { 10926 if (DEBUG_INSTALL) { 10927 if (chatty) 10928 Log.d(TAG, "Removing package " + ps.name); 10929 } 10930 10931 // writer 10932 synchronized (mPackages) { 10933 mPackages.remove(ps.name); 10934 final PackageParser.Package pkg = ps.pkg; 10935 if (pkg != null) { 10936 cleanPackageDataStructuresLILPw(pkg, chatty); 10937 } 10938 } 10939 } 10940 10941 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 10942 if (DEBUG_INSTALL) { 10943 if (chatty) 10944 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 10945 } 10946 10947 // writer 10948 synchronized (mPackages) { 10949 // Remove the parent package 10950 mPackages.remove(pkg.applicationInfo.packageName); 10951 cleanPackageDataStructuresLILPw(pkg, chatty); 10952 10953 // Remove the child packages 10954 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10955 for (int i = 0; i < childCount; i++) { 10956 PackageParser.Package childPkg = pkg.childPackages.get(i); 10957 mPackages.remove(childPkg.applicationInfo.packageName); 10958 cleanPackageDataStructuresLILPw(childPkg, chatty); 10959 } 10960 } 10961 } 10962 10963 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 10964 int N = pkg.providers.size(); 10965 StringBuilder r = null; 10966 int i; 10967 for (i=0; i<N; i++) { 10968 PackageParser.Provider p = pkg.providers.get(i); 10969 mProviders.removeProvider(p); 10970 if (p.info.authority == null) { 10971 10972 /* There was another ContentProvider with this authority when 10973 * this app was installed so this authority is null, 10974 * Ignore it as we don't have to unregister the provider. 10975 */ 10976 continue; 10977 } 10978 String names[] = p.info.authority.split(";"); 10979 for (int j = 0; j < names.length; j++) { 10980 if (mProvidersByAuthority.get(names[j]) == p) { 10981 mProvidersByAuthority.remove(names[j]); 10982 if (DEBUG_REMOVE) { 10983 if (chatty) 10984 Log.d(TAG, "Unregistered content provider: " + names[j] 10985 + ", className = " + p.info.name + ", isSyncable = " 10986 + p.info.isSyncable); 10987 } 10988 } 10989 } 10990 if (DEBUG_REMOVE && chatty) { 10991 if (r == null) { 10992 r = new StringBuilder(256); 10993 } else { 10994 r.append(' '); 10995 } 10996 r.append(p.info.name); 10997 } 10998 } 10999 if (r != null) { 11000 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 11001 } 11002 11003 N = pkg.services.size(); 11004 r = null; 11005 for (i=0; i<N; i++) { 11006 PackageParser.Service s = pkg.services.get(i); 11007 mServices.removeService(s); 11008 if (chatty) { 11009 if (r == null) { 11010 r = new StringBuilder(256); 11011 } else { 11012 r.append(' '); 11013 } 11014 r.append(s.info.name); 11015 } 11016 } 11017 if (r != null) { 11018 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 11019 } 11020 11021 N = pkg.receivers.size(); 11022 r = null; 11023 for (i=0; i<N; i++) { 11024 PackageParser.Activity a = pkg.receivers.get(i); 11025 mReceivers.removeActivity(a, "receiver"); 11026 if (DEBUG_REMOVE && chatty) { 11027 if (r == null) { 11028 r = new StringBuilder(256); 11029 } else { 11030 r.append(' '); 11031 } 11032 r.append(a.info.name); 11033 } 11034 } 11035 if (r != null) { 11036 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 11037 } 11038 11039 N = pkg.activities.size(); 11040 r = null; 11041 for (i=0; i<N; i++) { 11042 PackageParser.Activity a = pkg.activities.get(i); 11043 mActivities.removeActivity(a, "activity"); 11044 if (DEBUG_REMOVE && chatty) { 11045 if (r == null) { 11046 r = new StringBuilder(256); 11047 } else { 11048 r.append(' '); 11049 } 11050 r.append(a.info.name); 11051 } 11052 } 11053 if (r != null) { 11054 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 11055 } 11056 11057 N = pkg.permissions.size(); 11058 r = null; 11059 for (i=0; i<N; i++) { 11060 PackageParser.Permission p = pkg.permissions.get(i); 11061 BasePermission bp = mSettings.mPermissions.get(p.info.name); 11062 if (bp == null) { 11063 bp = mSettings.mPermissionTrees.get(p.info.name); 11064 } 11065 if (bp != null && bp.perm == p) { 11066 bp.perm = null; 11067 if (DEBUG_REMOVE && chatty) { 11068 if (r == null) { 11069 r = new StringBuilder(256); 11070 } else { 11071 r.append(' '); 11072 } 11073 r.append(p.info.name); 11074 } 11075 } 11076 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11077 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 11078 if (appOpPkgs != null) { 11079 appOpPkgs.remove(pkg.packageName); 11080 } 11081 } 11082 } 11083 if (r != null) { 11084 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 11085 } 11086 11087 N = pkg.requestedPermissions.size(); 11088 r = null; 11089 for (i=0; i<N; i++) { 11090 String perm = pkg.requestedPermissions.get(i); 11091 BasePermission bp = mSettings.mPermissions.get(perm); 11092 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11093 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 11094 if (appOpPkgs != null) { 11095 appOpPkgs.remove(pkg.packageName); 11096 if (appOpPkgs.isEmpty()) { 11097 mAppOpPermissionPackages.remove(perm); 11098 } 11099 } 11100 } 11101 } 11102 if (r != null) { 11103 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 11104 } 11105 11106 N = pkg.instrumentation.size(); 11107 r = null; 11108 for (i=0; i<N; i++) { 11109 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 11110 mInstrumentation.remove(a.getComponentName()); 11111 if (DEBUG_REMOVE && chatty) { 11112 if (r == null) { 11113 r = new StringBuilder(256); 11114 } else { 11115 r.append(' '); 11116 } 11117 r.append(a.info.name); 11118 } 11119 } 11120 if (r != null) { 11121 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 11122 } 11123 11124 r = null; 11125 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11126 // Only system apps can hold shared libraries. 11127 if (pkg.libraryNames != null) { 11128 for (i = 0; i < pkg.libraryNames.size(); i++) { 11129 String name = pkg.libraryNames.get(i); 11130 if (removeSharedLibraryLPw(name, 0)) { 11131 if (DEBUG_REMOVE && chatty) { 11132 if (r == null) { 11133 r = new StringBuilder(256); 11134 } else { 11135 r.append(' '); 11136 } 11137 r.append(name); 11138 } 11139 } 11140 } 11141 } 11142 } 11143 11144 r = null; 11145 11146 // Any package can hold static shared libraries. 11147 if (pkg.staticSharedLibName != null) { 11148 if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) { 11149 if (DEBUG_REMOVE && chatty) { 11150 if (r == null) { 11151 r = new StringBuilder(256); 11152 } else { 11153 r.append(' '); 11154 } 11155 r.append(pkg.staticSharedLibName); 11156 } 11157 } 11158 } 11159 11160 if (r != null) { 11161 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 11162 } 11163 } 11164 11165 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 11166 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 11167 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 11168 return true; 11169 } 11170 } 11171 return false; 11172 } 11173 11174 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 11175 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 11176 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 11177 11178 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 11179 // Update the parent permissions 11180 updatePermissionsLPw(pkg.packageName, pkg, flags); 11181 // Update the child permissions 11182 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 11183 for (int i = 0; i < childCount; i++) { 11184 PackageParser.Package childPkg = pkg.childPackages.get(i); 11185 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 11186 } 11187 } 11188 11189 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 11190 int flags) { 11191 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 11192 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 11193 } 11194 11195 private void updatePermissionsLPw(String changingPkg, 11196 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 11197 // Make sure there are no dangling permission trees. 11198 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 11199 while (it.hasNext()) { 11200 final BasePermission bp = it.next(); 11201 if (bp.packageSetting == null) { 11202 // We may not yet have parsed the package, so just see if 11203 // we still know about its settings. 11204 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 11205 } 11206 if (bp.packageSetting == null) { 11207 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 11208 + " from package " + bp.sourcePackage); 11209 it.remove(); 11210 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 11211 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 11212 Slog.i(TAG, "Removing old permission tree: " + bp.name 11213 + " from package " + bp.sourcePackage); 11214 flags |= UPDATE_PERMISSIONS_ALL; 11215 it.remove(); 11216 } 11217 } 11218 } 11219 11220 // Make sure all dynamic permissions have been assigned to a package, 11221 // and make sure there are no dangling permissions. 11222 it = mSettings.mPermissions.values().iterator(); 11223 while (it.hasNext()) { 11224 final BasePermission bp = it.next(); 11225 if (bp.type == BasePermission.TYPE_DYNAMIC) { 11226 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 11227 + bp.name + " pkg=" + bp.sourcePackage 11228 + " info=" + bp.pendingInfo); 11229 if (bp.packageSetting == null && bp.pendingInfo != null) { 11230 final BasePermission tree = findPermissionTreeLP(bp.name); 11231 if (tree != null && tree.perm != null) { 11232 bp.packageSetting = tree.packageSetting; 11233 bp.perm = new PackageParser.Permission(tree.perm.owner, 11234 new PermissionInfo(bp.pendingInfo)); 11235 bp.perm.info.packageName = tree.perm.info.packageName; 11236 bp.perm.info.name = bp.name; 11237 bp.uid = tree.uid; 11238 } 11239 } 11240 } 11241 if (bp.packageSetting == null) { 11242 // We may not yet have parsed the package, so just see if 11243 // we still know about its settings. 11244 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 11245 } 11246 if (bp.packageSetting == null) { 11247 Slog.w(TAG, "Removing dangling permission: " + bp.name 11248 + " from package " + bp.sourcePackage); 11249 it.remove(); 11250 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 11251 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 11252 Slog.i(TAG, "Removing old permission: " + bp.name 11253 + " from package " + bp.sourcePackage); 11254 flags |= UPDATE_PERMISSIONS_ALL; 11255 it.remove(); 11256 } 11257 } 11258 } 11259 11260 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 11261 // Now update the permissions for all packages, in particular 11262 // replace the granted permissions of the system packages. 11263 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 11264 for (PackageParser.Package pkg : mPackages.values()) { 11265 if (pkg != pkgInfo) { 11266 // Only replace for packages on requested volume 11267 final String volumeUuid = getVolumeUuidForPackage(pkg); 11268 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 11269 && Objects.equals(replaceVolumeUuid, volumeUuid); 11270 grantPermissionsLPw(pkg, replace, changingPkg); 11271 } 11272 } 11273 } 11274 11275 if (pkgInfo != null) { 11276 // Only replace for packages on requested volume 11277 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 11278 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 11279 && Objects.equals(replaceVolumeUuid, volumeUuid); 11280 grantPermissionsLPw(pkgInfo, replace, changingPkg); 11281 } 11282 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 11283 } 11284 11285 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 11286 String packageOfInterest) { 11287 // IMPORTANT: There are two types of permissions: install and runtime. 11288 // Install time permissions are granted when the app is installed to 11289 // all device users and users added in the future. Runtime permissions 11290 // are granted at runtime explicitly to specific users. Normal and signature 11291 // protected permissions are install time permissions. Dangerous permissions 11292 // are install permissions if the app's target SDK is Lollipop MR1 or older, 11293 // otherwise they are runtime permissions. This function does not manage 11294 // runtime permissions except for the case an app targeting Lollipop MR1 11295 // being upgraded to target a newer SDK, in which case dangerous permissions 11296 // are transformed from install time to runtime ones. 11297 11298 final PackageSetting ps = (PackageSetting) pkg.mExtras; 11299 if (ps == null) { 11300 return; 11301 } 11302 11303 PermissionsState permissionsState = ps.getPermissionsState(); 11304 PermissionsState origPermissions = permissionsState; 11305 11306 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 11307 11308 boolean runtimePermissionsRevoked = false; 11309 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 11310 11311 boolean changedInstallPermission = false; 11312 11313 if (replace) { 11314 ps.installPermissionsFixed = false; 11315 if (!ps.isSharedUser()) { 11316 origPermissions = new PermissionsState(permissionsState); 11317 permissionsState.reset(); 11318 } else { 11319 // We need to know only about runtime permission changes since the 11320 // calling code always writes the install permissions state but 11321 // the runtime ones are written only if changed. The only cases of 11322 // changed runtime permissions here are promotion of an install to 11323 // runtime and revocation of a runtime from a shared user. 11324 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 11325 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 11326 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 11327 runtimePermissionsRevoked = true; 11328 } 11329 } 11330 } 11331 11332 permissionsState.setGlobalGids(mGlobalGids); 11333 11334 final int N = pkg.requestedPermissions.size(); 11335 for (int i=0; i<N; i++) { 11336 final String name = pkg.requestedPermissions.get(i); 11337 final BasePermission bp = mSettings.mPermissions.get(name); 11338 11339 if (DEBUG_INSTALL) { 11340 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 11341 } 11342 11343 if (bp == null || bp.packageSetting == null) { 11344 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 11345 Slog.w(TAG, "Unknown permission " + name 11346 + " in package " + pkg.packageName); 11347 } 11348 continue; 11349 } 11350 11351 11352 // Limit ephemeral apps to ephemeral allowed permissions. 11353 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) { 11354 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package " 11355 + pkg.packageName); 11356 continue; 11357 } 11358 11359 final String perm = bp.name; 11360 boolean allowedSig = false; 11361 int grant = GRANT_DENIED; 11362 11363 // Keep track of app op permissions. 11364 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 11365 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 11366 if (pkgs == null) { 11367 pkgs = new ArraySet<>(); 11368 mAppOpPermissionPackages.put(bp.name, pkgs); 11369 } 11370 pkgs.add(pkg.packageName); 11371 } 11372 11373 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 11374 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 11375 >= Build.VERSION_CODES.M; 11376 switch (level) { 11377 case PermissionInfo.PROTECTION_NORMAL: { 11378 // For all apps normal permissions are install time ones. 11379 grant = GRANT_INSTALL; 11380 } break; 11381 11382 case PermissionInfo.PROTECTION_DANGEROUS: { 11383 // If a permission review is required for legacy apps we represent 11384 // their permissions as always granted runtime ones since we need 11385 // to keep the review required permission flag per user while an 11386 // install permission's state is shared across all users. 11387 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) { 11388 // For legacy apps dangerous permissions are install time ones. 11389 grant = GRANT_INSTALL; 11390 } else if (origPermissions.hasInstallPermission(bp.name)) { 11391 // For legacy apps that became modern, install becomes runtime. 11392 grant = GRANT_UPGRADE; 11393 } else if (mPromoteSystemApps 11394 && isSystemApp(ps) 11395 && mExistingSystemPackages.contains(ps.name)) { 11396 // For legacy system apps, install becomes runtime. 11397 // We cannot check hasInstallPermission() for system apps since those 11398 // permissions were granted implicitly and not persisted pre-M. 11399 grant = GRANT_UPGRADE; 11400 } else { 11401 // For modern apps keep runtime permissions unchanged. 11402 grant = GRANT_RUNTIME; 11403 } 11404 } break; 11405 11406 case PermissionInfo.PROTECTION_SIGNATURE: { 11407 // For all apps signature permissions are install time ones. 11408 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 11409 if (allowedSig) { 11410 grant = GRANT_INSTALL; 11411 } 11412 } break; 11413 } 11414 11415 if (DEBUG_INSTALL) { 11416 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 11417 } 11418 11419 if (grant != GRANT_DENIED) { 11420 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 11421 // If this is an existing, non-system package, then 11422 // we can't add any new permissions to it. 11423 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 11424 // Except... if this is a permission that was added 11425 // to the platform (note: need to only do this when 11426 // updating the platform). 11427 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 11428 grant = GRANT_DENIED; 11429 } 11430 } 11431 } 11432 11433 switch (grant) { 11434 case GRANT_INSTALL: { 11435 // Revoke this as runtime permission to handle the case of 11436 // a runtime permission being downgraded to an install one. 11437 // Also in permission review mode we keep dangerous permissions 11438 // for legacy apps 11439 for (int userId : UserManagerService.getInstance().getUserIds()) { 11440 if (origPermissions.getRuntimePermissionState( 11441 bp.name, userId) != null) { 11442 // Revoke the runtime permission and clear the flags. 11443 origPermissions.revokeRuntimePermission(bp, userId); 11444 origPermissions.updatePermissionFlags(bp, userId, 11445 PackageManager.MASK_PERMISSION_FLAGS, 0); 11446 // If we revoked a permission permission, we have to write. 11447 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11448 changedRuntimePermissionUserIds, userId); 11449 } 11450 } 11451 // Grant an install permission. 11452 if (permissionsState.grantInstallPermission(bp) != 11453 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11454 changedInstallPermission = true; 11455 } 11456 } break; 11457 11458 case GRANT_RUNTIME: { 11459 // Grant previously granted runtime permissions. 11460 for (int userId : UserManagerService.getInstance().getUserIds()) { 11461 PermissionState permissionState = origPermissions 11462 .getRuntimePermissionState(bp.name, userId); 11463 int flags = permissionState != null 11464 ? permissionState.getFlags() : 0; 11465 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 11466 // Don't propagate the permission in a permission review mode if 11467 // the former was revoked, i.e. marked to not propagate on upgrade. 11468 // Note that in a permission review mode install permissions are 11469 // represented as constantly granted runtime ones since we need to 11470 // keep a per user state associated with the permission. Also the 11471 // revoke on upgrade flag is no longer applicable and is reset. 11472 final boolean revokeOnUpgrade = (flags & PackageManager 11473 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 11474 if (revokeOnUpgrade) { 11475 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 11476 // Since we changed the flags, we have to write. 11477 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11478 changedRuntimePermissionUserIds, userId); 11479 } 11480 if (!mPermissionReviewRequired || !revokeOnUpgrade) { 11481 if (permissionsState.grantRuntimePermission(bp, userId) == 11482 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11483 // If we cannot put the permission as it was, 11484 // we have to write. 11485 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11486 changedRuntimePermissionUserIds, userId); 11487 } 11488 } 11489 11490 // If the app supports runtime permissions no need for a review. 11491 if (mPermissionReviewRequired 11492 && appSupportsRuntimePermissions 11493 && (flags & PackageManager 11494 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 11495 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 11496 // Since we changed the flags, we have to write. 11497 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11498 changedRuntimePermissionUserIds, userId); 11499 } 11500 } else if (mPermissionReviewRequired 11501 && !appSupportsRuntimePermissions) { 11502 // For legacy apps that need a permission review, every new 11503 // runtime permission is granted but it is pending a review. 11504 // We also need to review only platform defined runtime 11505 // permissions as these are the only ones the platform knows 11506 // how to disable the API to simulate revocation as legacy 11507 // apps don't expect to run with revoked permissions. 11508 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 11509 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 11510 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 11511 // We changed the flags, hence have to write. 11512 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11513 changedRuntimePermissionUserIds, userId); 11514 } 11515 } 11516 if (permissionsState.grantRuntimePermission(bp, userId) 11517 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 11518 // We changed the permission, hence have to write. 11519 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11520 changedRuntimePermissionUserIds, userId); 11521 } 11522 } 11523 // Propagate the permission flags. 11524 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 11525 } 11526 } break; 11527 11528 case GRANT_UPGRADE: { 11529 // Grant runtime permissions for a previously held install permission. 11530 PermissionState permissionState = origPermissions 11531 .getInstallPermissionState(bp.name); 11532 final int flags = permissionState != null ? permissionState.getFlags() : 0; 11533 11534 if (origPermissions.revokeInstallPermission(bp) 11535 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 11536 // We will be transferring the permission flags, so clear them. 11537 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 11538 PackageManager.MASK_PERMISSION_FLAGS, 0); 11539 changedInstallPermission = true; 11540 } 11541 11542 // If the permission is not to be promoted to runtime we ignore it and 11543 // also its other flags as they are not applicable to install permissions. 11544 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 11545 for (int userId : currentUserIds) { 11546 if (permissionsState.grantRuntimePermission(bp, userId) != 11547 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11548 // Transfer the permission flags. 11549 permissionsState.updatePermissionFlags(bp, userId, 11550 flags, flags); 11551 // If we granted the permission, we have to write. 11552 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 11553 changedRuntimePermissionUserIds, userId); 11554 } 11555 } 11556 } 11557 } break; 11558 11559 default: { 11560 if (packageOfInterest == null 11561 || packageOfInterest.equals(pkg.packageName)) { 11562 Slog.w(TAG, "Not granting permission " + perm 11563 + " to package " + pkg.packageName 11564 + " because it was previously installed without"); 11565 } 11566 } break; 11567 } 11568 } else { 11569 if (permissionsState.revokeInstallPermission(bp) != 11570 PermissionsState.PERMISSION_OPERATION_FAILURE) { 11571 // Also drop the permission flags. 11572 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 11573 PackageManager.MASK_PERMISSION_FLAGS, 0); 11574 changedInstallPermission = true; 11575 Slog.i(TAG, "Un-granting permission " + perm 11576 + " from package " + pkg.packageName 11577 + " (protectionLevel=" + bp.protectionLevel 11578 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 11579 + ")"); 11580 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 11581 // Don't print warning for app op permissions, since it is fine for them 11582 // not to be granted, there is a UI for the user to decide. 11583 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 11584 Slog.w(TAG, "Not granting permission " + perm 11585 + " to package " + pkg.packageName 11586 + " (protectionLevel=" + bp.protectionLevel 11587 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 11588 + ")"); 11589 } 11590 } 11591 } 11592 } 11593 11594 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 11595 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 11596 // This is the first that we have heard about this package, so the 11597 // permissions we have now selected are fixed until explicitly 11598 // changed. 11599 ps.installPermissionsFixed = true; 11600 } 11601 11602 // Persist the runtime permissions state for users with changes. If permissions 11603 // were revoked because no app in the shared user declares them we have to 11604 // write synchronously to avoid losing runtime permissions state. 11605 for (int userId : changedRuntimePermissionUserIds) { 11606 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 11607 } 11608 } 11609 11610 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 11611 boolean allowed = false; 11612 final int NP = PackageParser.NEW_PERMISSIONS.length; 11613 for (int ip=0; ip<NP; ip++) { 11614 final PackageParser.NewPermissionInfo npi 11615 = PackageParser.NEW_PERMISSIONS[ip]; 11616 if (npi.name.equals(perm) 11617 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 11618 allowed = true; 11619 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 11620 + pkg.packageName); 11621 break; 11622 } 11623 } 11624 return allowed; 11625 } 11626 11627 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 11628 BasePermission bp, PermissionsState origPermissions) { 11629 boolean privilegedPermission = (bp.protectionLevel 11630 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0; 11631 boolean privappPermissionsDisable = 11632 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE; 11633 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage); 11634 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName); 11635 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp() 11636 && !platformPackage && platformPermission) { 11637 ArraySet<String> wlPermissions = SystemConfig.getInstance() 11638 .getPrivAppPermissions(pkg.packageName); 11639 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm); 11640 if (!whitelisted) { 11641 Slog.w(TAG, "Privileged permission " + perm + " for package " 11642 + pkg.packageName + " - not in privapp-permissions whitelist"); 11643 // Only report violations for apps on system image 11644 if (!mSystemReady && !pkg.isUpdatedSystemApp()) { 11645 if (mPrivappPermissionsViolations == null) { 11646 mPrivappPermissionsViolations = new ArraySet<>(); 11647 } 11648 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm); 11649 } 11650 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { 11651 return false; 11652 } 11653 } 11654 } 11655 boolean allowed = (compareSignatures( 11656 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 11657 == PackageManager.SIGNATURE_MATCH) 11658 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 11659 == PackageManager.SIGNATURE_MATCH); 11660 if (!allowed && privilegedPermission) { 11661 if (isSystemApp(pkg)) { 11662 // For updated system applications, a system permission 11663 // is granted only if it had been defined by the original application. 11664 if (pkg.isUpdatedSystemApp()) { 11665 final PackageSetting sysPs = mSettings 11666 .getDisabledSystemPkgLPr(pkg.packageName); 11667 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 11668 // If the original was granted this permission, we take 11669 // that grant decision as read and propagate it to the 11670 // update. 11671 if (sysPs.isPrivileged()) { 11672 allowed = true; 11673 } 11674 } else { 11675 // The system apk may have been updated with an older 11676 // version of the one on the data partition, but which 11677 // granted a new system permission that it didn't have 11678 // before. In this case we do want to allow the app to 11679 // now get the new permission if the ancestral apk is 11680 // privileged to get it. 11681 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 11682 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 11683 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 11684 allowed = true; 11685 break; 11686 } 11687 } 11688 } 11689 // Also if a privileged parent package on the system image or any of 11690 // its children requested a privileged permission, the updated child 11691 // packages can also get the permission. 11692 if (pkg.parentPackage != null) { 11693 final PackageSetting disabledSysParentPs = mSettings 11694 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 11695 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 11696 && disabledSysParentPs.isPrivileged()) { 11697 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 11698 allowed = true; 11699 } else if (disabledSysParentPs.pkg.childPackages != null) { 11700 final int count = disabledSysParentPs.pkg.childPackages.size(); 11701 for (int i = 0; i < count; i++) { 11702 PackageParser.Package disabledSysChildPkg = 11703 disabledSysParentPs.pkg.childPackages.get(i); 11704 if (isPackageRequestingPermission(disabledSysChildPkg, 11705 perm)) { 11706 allowed = true; 11707 break; 11708 } 11709 } 11710 } 11711 } 11712 } 11713 } 11714 } else { 11715 allowed = isPrivilegedApp(pkg); 11716 } 11717 } 11718 } 11719 if (!allowed) { 11720 if (!allowed && (bp.protectionLevel 11721 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 11722 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 11723 // If this was a previously normal/dangerous permission that got moved 11724 // to a system permission as part of the runtime permission redesign, then 11725 // we still want to blindly grant it to old apps. 11726 allowed = true; 11727 } 11728 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 11729 && pkg.packageName.equals(mRequiredInstallerPackage)) { 11730 // If this permission is to be granted to the system installer and 11731 // this app is an installer, then it gets the permission. 11732 allowed = true; 11733 } 11734 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 11735 && pkg.packageName.equals(mRequiredVerifierPackage)) { 11736 // If this permission is to be granted to the system verifier and 11737 // this app is a verifier, then it gets the permission. 11738 allowed = true; 11739 } 11740 if (!allowed && (bp.protectionLevel 11741 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 11742 && isSystemApp(pkg)) { 11743 // Any pre-installed system app is allowed to get this permission. 11744 allowed = true; 11745 } 11746 if (!allowed && (bp.protectionLevel 11747 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 11748 // For development permissions, a development permission 11749 // is granted only if it was already granted. 11750 allowed = origPermissions.hasInstallPermission(perm); 11751 } 11752 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 11753 && pkg.packageName.equals(mSetupWizardPackage)) { 11754 // If this permission is to be granted to the system setup wizard and 11755 // this app is a setup wizard, then it gets the permission. 11756 allowed = true; 11757 } 11758 } 11759 return allowed; 11760 } 11761 11762 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 11763 final int permCount = pkg.requestedPermissions.size(); 11764 for (int j = 0; j < permCount; j++) { 11765 String requestedPermission = pkg.requestedPermissions.get(j); 11766 if (permission.equals(requestedPermission)) { 11767 return true; 11768 } 11769 } 11770 return false; 11771 } 11772 11773 final class ActivityIntentResolver 11774 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 11775 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11776 boolean defaultOnly, int userId) { 11777 if (!sUserManager.exists(userId)) return null; 11778 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0); 11779 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11780 } 11781 11782 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11783 int userId) { 11784 if (!sUserManager.exists(userId)) return null; 11785 mFlags = flags; 11786 return super.queryIntent(intent, resolvedType, 11787 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 11788 userId); 11789 } 11790 11791 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11792 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 11793 if (!sUserManager.exists(userId)) return null; 11794 if (packageActivities == null) { 11795 return null; 11796 } 11797 mFlags = flags; 11798 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11799 final int N = packageActivities.size(); 11800 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 11801 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 11802 11803 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 11804 for (int i = 0; i < N; ++i) { 11805 intentFilters = packageActivities.get(i).intents; 11806 if (intentFilters != null && intentFilters.size() > 0) { 11807 PackageParser.ActivityIntentInfo[] array = 11808 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 11809 intentFilters.toArray(array); 11810 listCut.add(array); 11811 } 11812 } 11813 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11814 } 11815 11816 /** 11817 * Finds a privileged activity that matches the specified activity names. 11818 */ 11819 private PackageParser.Activity findMatchingActivity( 11820 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 11821 for (PackageParser.Activity sysActivity : activityList) { 11822 if (sysActivity.info.name.equals(activityInfo.name)) { 11823 return sysActivity; 11824 } 11825 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 11826 return sysActivity; 11827 } 11828 if (sysActivity.info.targetActivity != null) { 11829 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 11830 return sysActivity; 11831 } 11832 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 11833 return sysActivity; 11834 } 11835 } 11836 } 11837 return null; 11838 } 11839 11840 public class IterGenerator<E> { 11841 public Iterator<E> generate(ActivityIntentInfo info) { 11842 return null; 11843 } 11844 } 11845 11846 public class ActionIterGenerator extends IterGenerator<String> { 11847 @Override 11848 public Iterator<String> generate(ActivityIntentInfo info) { 11849 return info.actionsIterator(); 11850 } 11851 } 11852 11853 public class CategoriesIterGenerator extends IterGenerator<String> { 11854 @Override 11855 public Iterator<String> generate(ActivityIntentInfo info) { 11856 return info.categoriesIterator(); 11857 } 11858 } 11859 11860 public class SchemesIterGenerator extends IterGenerator<String> { 11861 @Override 11862 public Iterator<String> generate(ActivityIntentInfo info) { 11863 return info.schemesIterator(); 11864 } 11865 } 11866 11867 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 11868 @Override 11869 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 11870 return info.authoritiesIterator(); 11871 } 11872 } 11873 11874 /** 11875 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 11876 * MODIFIED. Do not pass in a list that should not be changed. 11877 */ 11878 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 11879 IterGenerator<T> generator, Iterator<T> searchIterator) { 11880 // loop through the set of actions; every one must be found in the intent filter 11881 while (searchIterator.hasNext()) { 11882 // we must have at least one filter in the list to consider a match 11883 if (intentList.size() == 0) { 11884 break; 11885 } 11886 11887 final T searchAction = searchIterator.next(); 11888 11889 // loop through the set of intent filters 11890 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 11891 while (intentIter.hasNext()) { 11892 final ActivityIntentInfo intentInfo = intentIter.next(); 11893 boolean selectionFound = false; 11894 11895 // loop through the intent filter's selection criteria; at least one 11896 // of them must match the searched criteria 11897 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 11898 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 11899 final T intentSelection = intentSelectionIter.next(); 11900 if (intentSelection != null && intentSelection.equals(searchAction)) { 11901 selectionFound = true; 11902 break; 11903 } 11904 } 11905 11906 // the selection criteria wasn't found in this filter's set; this filter 11907 // is not a potential match 11908 if (!selectionFound) { 11909 intentIter.remove(); 11910 } 11911 } 11912 } 11913 } 11914 11915 private boolean isProtectedAction(ActivityIntentInfo filter) { 11916 final Iterator<String> actionsIter = filter.actionsIterator(); 11917 while (actionsIter != null && actionsIter.hasNext()) { 11918 final String filterAction = actionsIter.next(); 11919 if (PROTECTED_ACTIONS.contains(filterAction)) { 11920 return true; 11921 } 11922 } 11923 return false; 11924 } 11925 11926 /** 11927 * Adjusts the priority of the given intent filter according to policy. 11928 * <p> 11929 * <ul> 11930 * <li>The priority for non privileged applications is capped to '0'</li> 11931 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 11932 * <li>The priority for unbundled updates to privileged applications is capped to the 11933 * priority defined on the system partition</li> 11934 * </ul> 11935 * <p> 11936 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 11937 * allowed to obtain any priority on any action. 11938 */ 11939 private void adjustPriority( 11940 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 11941 // nothing to do; priority is fine as-is 11942 if (intent.getPriority() <= 0) { 11943 return; 11944 } 11945 11946 final ActivityInfo activityInfo = intent.activity.info; 11947 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 11948 11949 final boolean privilegedApp = 11950 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 11951 if (!privilegedApp) { 11952 // non-privileged applications can never define a priority >0 11953 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 11954 + " package: " + applicationInfo.packageName 11955 + " activity: " + intent.activity.className 11956 + " origPrio: " + intent.getPriority()); 11957 intent.setPriority(0); 11958 return; 11959 } 11960 11961 if (systemActivities == null) { 11962 // the system package is not disabled; we're parsing the system partition 11963 if (isProtectedAction(intent)) { 11964 if (mDeferProtectedFilters) { 11965 // We can't deal with these just yet. No component should ever obtain a 11966 // >0 priority for a protected actions, with ONE exception -- the setup 11967 // wizard. The setup wizard, however, cannot be known until we're able to 11968 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 11969 // until all intent filters have been processed. Chicken, meet egg. 11970 // Let the filter temporarily have a high priority and rectify the 11971 // priorities after all system packages have been scanned. 11972 mProtectedFilters.add(intent); 11973 if (DEBUG_FILTERS) { 11974 Slog.i(TAG, "Protected action; save for later;" 11975 + " package: " + applicationInfo.packageName 11976 + " activity: " + intent.activity.className 11977 + " origPrio: " + intent.getPriority()); 11978 } 11979 return; 11980 } else { 11981 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 11982 Slog.i(TAG, "No setup wizard;" 11983 + " All protected intents capped to priority 0"); 11984 } 11985 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 11986 if (DEBUG_FILTERS) { 11987 Slog.i(TAG, "Found setup wizard;" 11988 + " allow priority " + intent.getPriority() + ";" 11989 + " package: " + intent.activity.info.packageName 11990 + " activity: " + intent.activity.className 11991 + " priority: " + intent.getPriority()); 11992 } 11993 // setup wizard gets whatever it wants 11994 return; 11995 } 11996 Slog.w(TAG, "Protected action; cap priority to 0;" 11997 + " package: " + intent.activity.info.packageName 11998 + " activity: " + intent.activity.className 11999 + " origPrio: " + intent.getPriority()); 12000 intent.setPriority(0); 12001 return; 12002 } 12003 } 12004 // privileged apps on the system image get whatever priority they request 12005 return; 12006 } 12007 12008 // privileged app unbundled update ... try to find the same activity 12009 final PackageParser.Activity foundActivity = 12010 findMatchingActivity(systemActivities, activityInfo); 12011 if (foundActivity == null) { 12012 // this is a new activity; it cannot obtain >0 priority 12013 if (DEBUG_FILTERS) { 12014 Slog.i(TAG, "New activity; cap priority to 0;" 12015 + " package: " + applicationInfo.packageName 12016 + " activity: " + intent.activity.className 12017 + " origPrio: " + intent.getPriority()); 12018 } 12019 intent.setPriority(0); 12020 return; 12021 } 12022 12023 // found activity, now check for filter equivalence 12024 12025 // a shallow copy is enough; we modify the list, not its contents 12026 final List<ActivityIntentInfo> intentListCopy = 12027 new ArrayList<>(foundActivity.intents); 12028 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 12029 12030 // find matching action subsets 12031 final Iterator<String> actionsIterator = intent.actionsIterator(); 12032 if (actionsIterator != null) { 12033 getIntentListSubset( 12034 intentListCopy, new ActionIterGenerator(), actionsIterator); 12035 if (intentListCopy.size() == 0) { 12036 // no more intents to match; we're not equivalent 12037 if (DEBUG_FILTERS) { 12038 Slog.i(TAG, "Mismatched action; cap priority to 0;" 12039 + " package: " + applicationInfo.packageName 12040 + " activity: " + intent.activity.className 12041 + " origPrio: " + intent.getPriority()); 12042 } 12043 intent.setPriority(0); 12044 return; 12045 } 12046 } 12047 12048 // find matching category subsets 12049 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 12050 if (categoriesIterator != null) { 12051 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 12052 categoriesIterator); 12053 if (intentListCopy.size() == 0) { 12054 // no more intents to match; we're not equivalent 12055 if (DEBUG_FILTERS) { 12056 Slog.i(TAG, "Mismatched category; cap priority to 0;" 12057 + " package: " + applicationInfo.packageName 12058 + " activity: " + intent.activity.className 12059 + " origPrio: " + intent.getPriority()); 12060 } 12061 intent.setPriority(0); 12062 return; 12063 } 12064 } 12065 12066 // find matching schemes subsets 12067 final Iterator<String> schemesIterator = intent.schemesIterator(); 12068 if (schemesIterator != null) { 12069 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 12070 schemesIterator); 12071 if (intentListCopy.size() == 0) { 12072 // no more intents to match; we're not equivalent 12073 if (DEBUG_FILTERS) { 12074 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 12075 + " package: " + applicationInfo.packageName 12076 + " activity: " + intent.activity.className 12077 + " origPrio: " + intent.getPriority()); 12078 } 12079 intent.setPriority(0); 12080 return; 12081 } 12082 } 12083 12084 // find matching authorities subsets 12085 final Iterator<IntentFilter.AuthorityEntry> 12086 authoritiesIterator = intent.authoritiesIterator(); 12087 if (authoritiesIterator != null) { 12088 getIntentListSubset(intentListCopy, 12089 new AuthoritiesIterGenerator(), 12090 authoritiesIterator); 12091 if (intentListCopy.size() == 0) { 12092 // no more intents to match; we're not equivalent 12093 if (DEBUG_FILTERS) { 12094 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 12095 + " package: " + applicationInfo.packageName 12096 + " activity: " + intent.activity.className 12097 + " origPrio: " + intent.getPriority()); 12098 } 12099 intent.setPriority(0); 12100 return; 12101 } 12102 } 12103 12104 // we found matching filter(s); app gets the max priority of all intents 12105 int cappedPriority = 0; 12106 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 12107 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 12108 } 12109 if (intent.getPriority() > cappedPriority) { 12110 if (DEBUG_FILTERS) { 12111 Slog.i(TAG, "Found matching filter(s);" 12112 + " cap priority to " + cappedPriority + ";" 12113 + " package: " + applicationInfo.packageName 12114 + " activity: " + intent.activity.className 12115 + " origPrio: " + intent.getPriority()); 12116 } 12117 intent.setPriority(cappedPriority); 12118 return; 12119 } 12120 // all this for nothing; the requested priority was <= what was on the system 12121 } 12122 12123 public final void addActivity(PackageParser.Activity a, String type) { 12124 mActivities.put(a.getComponentName(), a); 12125 if (DEBUG_SHOW_INFO) 12126 Log.v( 12127 TAG, " " + type + " " + 12128 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 12129 if (DEBUG_SHOW_INFO) 12130 Log.v(TAG, " Class=" + a.info.name); 12131 final int NI = a.intents.size(); 12132 for (int j=0; j<NI; j++) { 12133 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 12134 if ("activity".equals(type)) { 12135 final PackageSetting ps = 12136 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 12137 final List<PackageParser.Activity> systemActivities = 12138 ps != null && ps.pkg != null ? ps.pkg.activities : null; 12139 adjustPriority(systemActivities, intent); 12140 } 12141 if (DEBUG_SHOW_INFO) { 12142 Log.v(TAG, " IntentFilter:"); 12143 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12144 } 12145 if (!intent.debugCheck()) { 12146 Log.w(TAG, "==> For Activity " + a.info.name); 12147 } 12148 addFilter(intent); 12149 } 12150 } 12151 12152 public final void removeActivity(PackageParser.Activity a, String type) { 12153 mActivities.remove(a.getComponentName()); 12154 if (DEBUG_SHOW_INFO) { 12155 Log.v(TAG, " " + type + " " 12156 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 12157 : a.info.name) + ":"); 12158 Log.v(TAG, " Class=" + a.info.name); 12159 } 12160 final int NI = a.intents.size(); 12161 for (int j=0; j<NI; j++) { 12162 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 12163 if (DEBUG_SHOW_INFO) { 12164 Log.v(TAG, " IntentFilter:"); 12165 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12166 } 12167 removeFilter(intent); 12168 } 12169 } 12170 12171 @Override 12172 protected boolean allowFilterResult( 12173 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 12174 ActivityInfo filterAi = filter.activity.info; 12175 for (int i=dest.size()-1; i>=0; i--) { 12176 ActivityInfo destAi = dest.get(i).activityInfo; 12177 if (destAi.name == filterAi.name 12178 && destAi.packageName == filterAi.packageName) { 12179 return false; 12180 } 12181 } 12182 return true; 12183 } 12184 12185 @Override 12186 protected ActivityIntentInfo[] newArray(int size) { 12187 return new ActivityIntentInfo[size]; 12188 } 12189 12190 @Override 12191 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 12192 if (!sUserManager.exists(userId)) return true; 12193 PackageParser.Package p = filter.activity.owner; 12194 if (p != null) { 12195 PackageSetting ps = (PackageSetting)p.mExtras; 12196 if (ps != null) { 12197 // System apps are never considered stopped for purposes of 12198 // filtering, because there may be no way for the user to 12199 // actually re-launch them. 12200 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 12201 && ps.getStopped(userId); 12202 } 12203 } 12204 return false; 12205 } 12206 12207 @Override 12208 protected boolean isPackageForFilter(String packageName, 12209 PackageParser.ActivityIntentInfo info) { 12210 return packageName.equals(info.activity.owner.packageName); 12211 } 12212 12213 @Override 12214 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 12215 int match, int userId) { 12216 if (!sUserManager.exists(userId)) return null; 12217 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 12218 return null; 12219 } 12220 final PackageParser.Activity activity = info.activity; 12221 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 12222 if (ps == null) { 12223 return null; 12224 } 12225 final PackageUserState userState = ps.readUserState(userId); 12226 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 12227 userState, userId); 12228 if (ai == null) { 12229 return null; 12230 } 12231 final boolean matchVisibleToInstantApp = 12232 (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; 12233 final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0; 12234 // throw out filters that aren't visible to ephemeral apps 12235 if (matchVisibleToInstantApp 12236 && !(info.isVisibleToInstantApp() || userState.instantApp)) { 12237 return null; 12238 } 12239 // throw out ephemeral filters if we're not explicitly requesting them 12240 if (!isInstantApp && userState.instantApp) { 12241 return null; 12242 } 12243 // throw out instant app filters if updates are available; will trigger 12244 // instant app resolution 12245 if (userState.instantApp && ps.isUpdateAvailable()) { 12246 return null; 12247 } 12248 final ResolveInfo res = new ResolveInfo(); 12249 res.activityInfo = ai; 12250 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 12251 res.filter = info; 12252 } 12253 if (info != null) { 12254 res.handleAllWebDataURI = info.handleAllWebDataURI(); 12255 } 12256 res.priority = info.getPriority(); 12257 res.preferredOrder = activity.owner.mPreferredOrder; 12258 //System.out.println("Result: " + res.activityInfo.className + 12259 // " = " + res.priority); 12260 res.match = match; 12261 res.isDefault = info.hasDefault; 12262 res.labelRes = info.labelRes; 12263 res.nonLocalizedLabel = info.nonLocalizedLabel; 12264 if (userNeedsBadging(userId)) { 12265 res.noResourceId = true; 12266 } else { 12267 res.icon = info.icon; 12268 } 12269 res.iconResourceId = info.icon; 12270 res.system = res.activityInfo.applicationInfo.isSystemApp(); 12271 res.instantAppAvailable = userState.instantApp; 12272 return res; 12273 } 12274 12275 @Override 12276 protected void sortResults(List<ResolveInfo> results) { 12277 Collections.sort(results, mResolvePrioritySorter); 12278 } 12279 12280 @Override 12281 protected void dumpFilter(PrintWriter out, String prefix, 12282 PackageParser.ActivityIntentInfo filter) { 12283 out.print(prefix); out.print( 12284 Integer.toHexString(System.identityHashCode(filter.activity))); 12285 out.print(' '); 12286 filter.activity.printComponentShortName(out); 12287 out.print(" filter "); 12288 out.println(Integer.toHexString(System.identityHashCode(filter))); 12289 } 12290 12291 @Override 12292 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 12293 return filter.activity; 12294 } 12295 12296 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12297 PackageParser.Activity activity = (PackageParser.Activity)label; 12298 out.print(prefix); out.print( 12299 Integer.toHexString(System.identityHashCode(activity))); 12300 out.print(' '); 12301 activity.printComponentShortName(out); 12302 if (count > 1) { 12303 out.print(" ("); out.print(count); out.print(" filters)"); 12304 } 12305 out.println(); 12306 } 12307 12308 // Keys are String (activity class name), values are Activity. 12309 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 12310 = new ArrayMap<ComponentName, PackageParser.Activity>(); 12311 private int mFlags; 12312 } 12313 12314 private final class ServiceIntentResolver 12315 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 12316 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 12317 boolean defaultOnly, int userId) { 12318 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 12319 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 12320 } 12321 12322 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 12323 int userId) { 12324 if (!sUserManager.exists(userId)) return null; 12325 mFlags = flags; 12326 return super.queryIntent(intent, resolvedType, 12327 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 12328 userId); 12329 } 12330 12331 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 12332 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 12333 if (!sUserManager.exists(userId)) return null; 12334 if (packageServices == null) { 12335 return null; 12336 } 12337 mFlags = flags; 12338 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 12339 final int N = packageServices.size(); 12340 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 12341 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 12342 12343 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 12344 for (int i = 0; i < N; ++i) { 12345 intentFilters = packageServices.get(i).intents; 12346 if (intentFilters != null && intentFilters.size() > 0) { 12347 PackageParser.ServiceIntentInfo[] array = 12348 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 12349 intentFilters.toArray(array); 12350 listCut.add(array); 12351 } 12352 } 12353 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 12354 } 12355 12356 public final void addService(PackageParser.Service s) { 12357 mServices.put(s.getComponentName(), s); 12358 if (DEBUG_SHOW_INFO) { 12359 Log.v(TAG, " " 12360 + (s.info.nonLocalizedLabel != null 12361 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 12362 Log.v(TAG, " Class=" + s.info.name); 12363 } 12364 final int NI = s.intents.size(); 12365 int j; 12366 for (j=0; j<NI; j++) { 12367 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 12368 if (DEBUG_SHOW_INFO) { 12369 Log.v(TAG, " IntentFilter:"); 12370 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12371 } 12372 if (!intent.debugCheck()) { 12373 Log.w(TAG, "==> For Service " + s.info.name); 12374 } 12375 addFilter(intent); 12376 } 12377 } 12378 12379 public final void removeService(PackageParser.Service s) { 12380 mServices.remove(s.getComponentName()); 12381 if (DEBUG_SHOW_INFO) { 12382 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 12383 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 12384 Log.v(TAG, " Class=" + s.info.name); 12385 } 12386 final int NI = s.intents.size(); 12387 int j; 12388 for (j=0; j<NI; j++) { 12389 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 12390 if (DEBUG_SHOW_INFO) { 12391 Log.v(TAG, " IntentFilter:"); 12392 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12393 } 12394 removeFilter(intent); 12395 } 12396 } 12397 12398 @Override 12399 protected boolean allowFilterResult( 12400 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 12401 ServiceInfo filterSi = filter.service.info; 12402 for (int i=dest.size()-1; i>=0; i--) { 12403 ServiceInfo destAi = dest.get(i).serviceInfo; 12404 if (destAi.name == filterSi.name 12405 && destAi.packageName == filterSi.packageName) { 12406 return false; 12407 } 12408 } 12409 return true; 12410 } 12411 12412 @Override 12413 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 12414 return new PackageParser.ServiceIntentInfo[size]; 12415 } 12416 12417 @Override 12418 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 12419 if (!sUserManager.exists(userId)) return true; 12420 PackageParser.Package p = filter.service.owner; 12421 if (p != null) { 12422 PackageSetting ps = (PackageSetting)p.mExtras; 12423 if (ps != null) { 12424 // System apps are never considered stopped for purposes of 12425 // filtering, because there may be no way for the user to 12426 // actually re-launch them. 12427 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 12428 && ps.getStopped(userId); 12429 } 12430 } 12431 return false; 12432 } 12433 12434 @Override 12435 protected boolean isPackageForFilter(String packageName, 12436 PackageParser.ServiceIntentInfo info) { 12437 return packageName.equals(info.service.owner.packageName); 12438 } 12439 12440 @Override 12441 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 12442 int match, int userId) { 12443 if (!sUserManager.exists(userId)) return null; 12444 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 12445 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 12446 return null; 12447 } 12448 final PackageParser.Service service = info.service; 12449 PackageSetting ps = (PackageSetting) service.owner.mExtras; 12450 if (ps == null) { 12451 return null; 12452 } 12453 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 12454 ps.readUserState(userId), userId); 12455 if (si == null) { 12456 return null; 12457 } 12458 final ResolveInfo res = new ResolveInfo(); 12459 res.serviceInfo = si; 12460 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 12461 res.filter = filter; 12462 } 12463 res.priority = info.getPriority(); 12464 res.preferredOrder = service.owner.mPreferredOrder; 12465 res.match = match; 12466 res.isDefault = info.hasDefault; 12467 res.labelRes = info.labelRes; 12468 res.nonLocalizedLabel = info.nonLocalizedLabel; 12469 res.icon = info.icon; 12470 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 12471 return res; 12472 } 12473 12474 @Override 12475 protected void sortResults(List<ResolveInfo> results) { 12476 Collections.sort(results, mResolvePrioritySorter); 12477 } 12478 12479 @Override 12480 protected void dumpFilter(PrintWriter out, String prefix, 12481 PackageParser.ServiceIntentInfo filter) { 12482 out.print(prefix); out.print( 12483 Integer.toHexString(System.identityHashCode(filter.service))); 12484 out.print(' '); 12485 filter.service.printComponentShortName(out); 12486 out.print(" filter "); 12487 out.println(Integer.toHexString(System.identityHashCode(filter))); 12488 } 12489 12490 @Override 12491 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 12492 return filter.service; 12493 } 12494 12495 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12496 PackageParser.Service service = (PackageParser.Service)label; 12497 out.print(prefix); out.print( 12498 Integer.toHexString(System.identityHashCode(service))); 12499 out.print(' '); 12500 service.printComponentShortName(out); 12501 if (count > 1) { 12502 out.print(" ("); out.print(count); out.print(" filters)"); 12503 } 12504 out.println(); 12505 } 12506 12507// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 12508// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 12509// final List<ResolveInfo> retList = Lists.newArrayList(); 12510// while (i.hasNext()) { 12511// final ResolveInfo resolveInfo = (ResolveInfo) i; 12512// if (isEnabledLP(resolveInfo.serviceInfo)) { 12513// retList.add(resolveInfo); 12514// } 12515// } 12516// return retList; 12517// } 12518 12519 // Keys are String (activity class name), values are Activity. 12520 private final ArrayMap<ComponentName, PackageParser.Service> mServices 12521 = new ArrayMap<ComponentName, PackageParser.Service>(); 12522 private int mFlags; 12523 } 12524 12525 private final class ProviderIntentResolver 12526 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 12527 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 12528 boolean defaultOnly, int userId) { 12529 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 12530 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 12531 } 12532 12533 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 12534 int userId) { 12535 if (!sUserManager.exists(userId)) 12536 return null; 12537 mFlags = flags; 12538 return super.queryIntent(intent, resolvedType, 12539 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 12540 userId); 12541 } 12542 12543 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 12544 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 12545 if (!sUserManager.exists(userId)) 12546 return null; 12547 if (packageProviders == null) { 12548 return null; 12549 } 12550 mFlags = flags; 12551 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 12552 final int N = packageProviders.size(); 12553 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 12554 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 12555 12556 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 12557 for (int i = 0; i < N; ++i) { 12558 intentFilters = packageProviders.get(i).intents; 12559 if (intentFilters != null && intentFilters.size() > 0) { 12560 PackageParser.ProviderIntentInfo[] array = 12561 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 12562 intentFilters.toArray(array); 12563 listCut.add(array); 12564 } 12565 } 12566 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 12567 } 12568 12569 public final void addProvider(PackageParser.Provider p) { 12570 if (mProviders.containsKey(p.getComponentName())) { 12571 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 12572 return; 12573 } 12574 12575 mProviders.put(p.getComponentName(), p); 12576 if (DEBUG_SHOW_INFO) { 12577 Log.v(TAG, " " 12578 + (p.info.nonLocalizedLabel != null 12579 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 12580 Log.v(TAG, " Class=" + p.info.name); 12581 } 12582 final int NI = p.intents.size(); 12583 int j; 12584 for (j = 0; j < NI; j++) { 12585 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 12586 if (DEBUG_SHOW_INFO) { 12587 Log.v(TAG, " IntentFilter:"); 12588 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12589 } 12590 if (!intent.debugCheck()) { 12591 Log.w(TAG, "==> For Provider " + p.info.name); 12592 } 12593 addFilter(intent); 12594 } 12595 } 12596 12597 public final void removeProvider(PackageParser.Provider p) { 12598 mProviders.remove(p.getComponentName()); 12599 if (DEBUG_SHOW_INFO) { 12600 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 12601 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 12602 Log.v(TAG, " Class=" + p.info.name); 12603 } 12604 final int NI = p.intents.size(); 12605 int j; 12606 for (j = 0; j < NI; j++) { 12607 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 12608 if (DEBUG_SHOW_INFO) { 12609 Log.v(TAG, " IntentFilter:"); 12610 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 12611 } 12612 removeFilter(intent); 12613 } 12614 } 12615 12616 @Override 12617 protected boolean allowFilterResult( 12618 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 12619 ProviderInfo filterPi = filter.provider.info; 12620 for (int i = dest.size() - 1; i >= 0; i--) { 12621 ProviderInfo destPi = dest.get(i).providerInfo; 12622 if (destPi.name == filterPi.name 12623 && destPi.packageName == filterPi.packageName) { 12624 return false; 12625 } 12626 } 12627 return true; 12628 } 12629 12630 @Override 12631 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 12632 return new PackageParser.ProviderIntentInfo[size]; 12633 } 12634 12635 @Override 12636 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 12637 if (!sUserManager.exists(userId)) 12638 return true; 12639 PackageParser.Package p = filter.provider.owner; 12640 if (p != null) { 12641 PackageSetting ps = (PackageSetting) p.mExtras; 12642 if (ps != null) { 12643 // System apps are never considered stopped for purposes of 12644 // filtering, because there may be no way for the user to 12645 // actually re-launch them. 12646 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 12647 && ps.getStopped(userId); 12648 } 12649 } 12650 return false; 12651 } 12652 12653 @Override 12654 protected boolean isPackageForFilter(String packageName, 12655 PackageParser.ProviderIntentInfo info) { 12656 return packageName.equals(info.provider.owner.packageName); 12657 } 12658 12659 @Override 12660 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 12661 int match, int userId) { 12662 if (!sUserManager.exists(userId)) 12663 return null; 12664 final PackageParser.ProviderIntentInfo info = filter; 12665 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 12666 return null; 12667 } 12668 final PackageParser.Provider provider = info.provider; 12669 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 12670 if (ps == null) { 12671 return null; 12672 } 12673 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 12674 ps.readUserState(userId), userId); 12675 if (pi == null) { 12676 return null; 12677 } 12678 final ResolveInfo res = new ResolveInfo(); 12679 res.providerInfo = pi; 12680 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 12681 res.filter = filter; 12682 } 12683 res.priority = info.getPriority(); 12684 res.preferredOrder = provider.owner.mPreferredOrder; 12685 res.match = match; 12686 res.isDefault = info.hasDefault; 12687 res.labelRes = info.labelRes; 12688 res.nonLocalizedLabel = info.nonLocalizedLabel; 12689 res.icon = info.icon; 12690 res.system = res.providerInfo.applicationInfo.isSystemApp(); 12691 return res; 12692 } 12693 12694 @Override 12695 protected void sortResults(List<ResolveInfo> results) { 12696 Collections.sort(results, mResolvePrioritySorter); 12697 } 12698 12699 @Override 12700 protected void dumpFilter(PrintWriter out, String prefix, 12701 PackageParser.ProviderIntentInfo filter) { 12702 out.print(prefix); 12703 out.print( 12704 Integer.toHexString(System.identityHashCode(filter.provider))); 12705 out.print(' '); 12706 filter.provider.printComponentShortName(out); 12707 out.print(" filter "); 12708 out.println(Integer.toHexString(System.identityHashCode(filter))); 12709 } 12710 12711 @Override 12712 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 12713 return filter.provider; 12714 } 12715 12716 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 12717 PackageParser.Provider provider = (PackageParser.Provider)label; 12718 out.print(prefix); out.print( 12719 Integer.toHexString(System.identityHashCode(provider))); 12720 out.print(' '); 12721 provider.printComponentShortName(out); 12722 if (count > 1) { 12723 out.print(" ("); out.print(count); out.print(" filters)"); 12724 } 12725 out.println(); 12726 } 12727 12728 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 12729 = new ArrayMap<ComponentName, PackageParser.Provider>(); 12730 private int mFlags; 12731 } 12732 12733 static final class EphemeralIntentResolver 12734 extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> { 12735 /** 12736 * The result that has the highest defined order. Ordering applies on a 12737 * per-package basis. Mapping is from package name to Pair of order and 12738 * EphemeralResolveInfo. 12739 * <p> 12740 * NOTE: This is implemented as a field variable for convenience and efficiency. 12741 * By having a field variable, we're able to track filter ordering as soon as 12742 * a non-zero order is defined. Otherwise, multiple loops across the result set 12743 * would be needed to apply ordering. If the intent resolver becomes re-entrant, 12744 * this needs to be contained entirely within {@link #filterResults}. 12745 */ 12746 final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>(); 12747 12748 @Override 12749 protected AuxiliaryResolveInfo[] newArray(int size) { 12750 return new AuxiliaryResolveInfo[size]; 12751 } 12752 12753 @Override 12754 protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) { 12755 return true; 12756 } 12757 12758 @Override 12759 protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match, 12760 int userId) { 12761 if (!sUserManager.exists(userId)) { 12762 return null; 12763 } 12764 final String packageName = responseObj.resolveInfo.getPackageName(); 12765 final Integer order = responseObj.getOrder(); 12766 final Pair<Integer, InstantAppResolveInfo> lastOrderResult = 12767 mOrderResult.get(packageName); 12768 // ordering is enabled and this item's order isn't high enough 12769 if (lastOrderResult != null && lastOrderResult.first >= order) { 12770 return null; 12771 } 12772 final InstantAppResolveInfo res = responseObj.resolveInfo; 12773 if (order > 0) { 12774 // non-zero order, enable ordering 12775 mOrderResult.put(packageName, new Pair<>(order, res)); 12776 } 12777 return responseObj; 12778 } 12779 12780 @Override 12781 protected void filterResults(List<AuxiliaryResolveInfo> results) { 12782 // only do work if ordering is enabled [most of the time it won't be] 12783 if (mOrderResult.size() == 0) { 12784 return; 12785 } 12786 int resultSize = results.size(); 12787 for (int i = 0; i < resultSize; i++) { 12788 final InstantAppResolveInfo info = results.get(i).resolveInfo; 12789 final String packageName = info.getPackageName(); 12790 final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName); 12791 if (savedInfo == null) { 12792 // package doesn't having ordering 12793 continue; 12794 } 12795 if (savedInfo.second == info) { 12796 // circled back to the highest ordered item; remove from order list 12797 mOrderResult.remove(savedInfo); 12798 if (mOrderResult.size() == 0) { 12799 // no more ordered items 12800 break; 12801 } 12802 continue; 12803 } 12804 // item has a worse order, remove it from the result list 12805 results.remove(i); 12806 resultSize--; 12807 i--; 12808 } 12809 } 12810 } 12811 12812 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 12813 new Comparator<ResolveInfo>() { 12814 public int compare(ResolveInfo r1, ResolveInfo r2) { 12815 int v1 = r1.priority; 12816 int v2 = r2.priority; 12817 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 12818 if (v1 != v2) { 12819 return (v1 > v2) ? -1 : 1; 12820 } 12821 v1 = r1.preferredOrder; 12822 v2 = r2.preferredOrder; 12823 if (v1 != v2) { 12824 return (v1 > v2) ? -1 : 1; 12825 } 12826 if (r1.isDefault != r2.isDefault) { 12827 return r1.isDefault ? -1 : 1; 12828 } 12829 v1 = r1.match; 12830 v2 = r2.match; 12831 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 12832 if (v1 != v2) { 12833 return (v1 > v2) ? -1 : 1; 12834 } 12835 if (r1.system != r2.system) { 12836 return r1.system ? -1 : 1; 12837 } 12838 if (r1.activityInfo != null) { 12839 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 12840 } 12841 if (r1.serviceInfo != null) { 12842 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 12843 } 12844 if (r1.providerInfo != null) { 12845 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 12846 } 12847 return 0; 12848 } 12849 }; 12850 12851 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 12852 new Comparator<ProviderInfo>() { 12853 public int compare(ProviderInfo p1, ProviderInfo p2) { 12854 final int v1 = p1.initOrder; 12855 final int v2 = p2.initOrder; 12856 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 12857 } 12858 }; 12859 12860 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 12861 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 12862 final int[] userIds) { 12863 mHandler.post(new Runnable() { 12864 @Override 12865 public void run() { 12866 try { 12867 final IActivityManager am = ActivityManager.getService(); 12868 if (am == null) return; 12869 final int[] resolvedUserIds; 12870 if (userIds == null) { 12871 resolvedUserIds = am.getRunningUserIds(); 12872 } else { 12873 resolvedUserIds = userIds; 12874 } 12875 for (int id : resolvedUserIds) { 12876 final Intent intent = new Intent(action, 12877 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 12878 if (extras != null) { 12879 intent.putExtras(extras); 12880 } 12881 if (targetPkg != null) { 12882 intent.setPackage(targetPkg); 12883 } 12884 // Modify the UID when posting to other users 12885 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 12886 if (uid > 0 && UserHandle.getUserId(uid) != id) { 12887 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 12888 intent.putExtra(Intent.EXTRA_UID, uid); 12889 } 12890 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 12891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 12892 if (DEBUG_BROADCASTS) { 12893 RuntimeException here = new RuntimeException("here"); 12894 here.fillInStackTrace(); 12895 Slog.d(TAG, "Sending to user " + id + ": " 12896 + intent.toShortString(false, true, false, false) 12897 + " " + intent.getExtras(), here); 12898 } 12899 am.broadcastIntent(null, intent, null, finishedReceiver, 12900 0, null, null, null, android.app.AppOpsManager.OP_NONE, 12901 null, finishedReceiver != null, false, id); 12902 } 12903 } catch (RemoteException ex) { 12904 } 12905 } 12906 }); 12907 } 12908 12909 /** 12910 * Check if the external storage media is available. This is true if there 12911 * is a mounted external storage medium or if the external storage is 12912 * emulated. 12913 */ 12914 private boolean isExternalMediaAvailable() { 12915 return mMediaMounted || Environment.isExternalStorageEmulated(); 12916 } 12917 12918 @Override 12919 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 12920 // writer 12921 synchronized (mPackages) { 12922 if (!isExternalMediaAvailable()) { 12923 // If the external storage is no longer mounted at this point, 12924 // the caller may not have been able to delete all of this 12925 // packages files and can not delete any more. Bail. 12926 return null; 12927 } 12928 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 12929 if (lastPackage != null) { 12930 pkgs.remove(lastPackage); 12931 } 12932 if (pkgs.size() > 0) { 12933 return pkgs.get(0); 12934 } 12935 } 12936 return null; 12937 } 12938 12939 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 12940 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 12941 userId, andCode ? 1 : 0, packageName); 12942 if (mSystemReady) { 12943 msg.sendToTarget(); 12944 } else { 12945 if (mPostSystemReadyMessages == null) { 12946 mPostSystemReadyMessages = new ArrayList<>(); 12947 } 12948 mPostSystemReadyMessages.add(msg); 12949 } 12950 } 12951 12952 void startCleaningPackages() { 12953 // reader 12954 if (!isExternalMediaAvailable()) { 12955 return; 12956 } 12957 synchronized (mPackages) { 12958 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 12959 return; 12960 } 12961 } 12962 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 12963 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 12964 IActivityManager am = ActivityManager.getService(); 12965 if (am != null) { 12966 try { 12967 am.startService(null, intent, null, -1, null, mContext.getOpPackageName(), 12968 UserHandle.USER_SYSTEM); 12969 } catch (RemoteException e) { 12970 } 12971 } 12972 } 12973 12974 @Override 12975 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 12976 int installFlags, String installerPackageName, int userId) { 12977 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 12978 12979 final int callingUid = Binder.getCallingUid(); 12980 enforceCrossUserPermission(callingUid, userId, 12981 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 12982 12983 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 12984 try { 12985 if (observer != null) { 12986 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 12987 } 12988 } catch (RemoteException re) { 12989 } 12990 return; 12991 } 12992 12993 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 12994 installFlags |= PackageManager.INSTALL_FROM_ADB; 12995 12996 } else { 12997 // Caller holds INSTALL_PACKAGES permission, so we're less strict 12998 // about installerPackageName. 12999 13000 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 13001 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 13002 } 13003 13004 UserHandle user; 13005 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 13006 user = UserHandle.ALL; 13007 } else { 13008 user = new UserHandle(userId); 13009 } 13010 13011 // Only system components can circumvent runtime permissions when installing. 13012 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 13013 && mContext.checkCallingOrSelfPermission(Manifest.permission 13014 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 13015 throw new SecurityException("You need the " 13016 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 13017 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 13018 } 13019 13020 if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0 13021 || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 13022 throw new IllegalArgumentException( 13023 "New installs into ASEC containers no longer supported"); 13024 } 13025 13026 final File originFile = new File(originPath); 13027 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 13028 13029 final Message msg = mHandler.obtainMessage(INIT_COPY); 13030 final VerificationInfo verificationInfo = new VerificationInfo( 13031 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 13032 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 13033 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 13034 null /*packageAbiOverride*/, null /*grantedPermissions*/, 13035 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN); 13036 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 13037 msg.obj = params; 13038 13039 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 13040 System.identityHashCode(msg.obj)); 13041 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 13042 System.identityHashCode(msg.obj)); 13043 13044 mHandler.sendMessage(msg); 13045 } 13046 13047 13048 /** 13049 * Ensure that the install reason matches what we know about the package installer (e.g. whether 13050 * it is acting on behalf on an enterprise or the user). 13051 * 13052 * Note that the ordering of the conditionals in this method is important. The checks we perform 13053 * are as follows, in this order: 13054 * 13055 * 1) If the install is being performed by a system app, we can trust the app to have set the 13056 * install reason correctly. Thus, we pass through the install reason unchanged, no matter 13057 * what it is. 13058 * 2) If the install is being performed by a device or profile owner app, the install reason 13059 * should be enterprise policy. However, we cannot be sure that the device or profile owner 13060 * set the install reason correctly. If the app targets an older SDK version where install 13061 * reasons did not exist yet, or if the app author simply forgot, the install reason may be 13062 * unset or wrong. Thus, we force the install reason to be enterprise policy. 13063 * 3) In all other cases, the install is being performed by a regular app that is neither part 13064 * of the system nor a device or profile owner. We have no reason to believe that this app is 13065 * acting on behalf of the enterprise admin. Thus, we check whether the install reason was 13066 * set to enterprise policy and if so, change it to unknown instead. 13067 */ 13068 private int fixUpInstallReason(String installerPackageName, int installerUid, 13069 int installReason) { 13070 if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid) 13071 == PERMISSION_GRANTED) { 13072 // If the install is being performed by a system app, we trust that app to have set the 13073 // install reason correctly. 13074 return installReason; 13075 } 13076 13077 final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 13078 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 13079 if (dpm != null) { 13080 ComponentName owner = null; 13081 try { 13082 owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */); 13083 if (owner == null) { 13084 owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid)); 13085 } 13086 } catch (RemoteException e) { 13087 } 13088 if (owner != null && owner.getPackageName().equals(installerPackageName)) { 13089 // If the install is being performed by a device or profile owner, the install 13090 // reason should be enterprise policy. 13091 return PackageManager.INSTALL_REASON_POLICY; 13092 } 13093 } 13094 13095 if (installReason == PackageManager.INSTALL_REASON_POLICY) { 13096 // If the install is being performed by a regular app (i.e. neither system app nor 13097 // device or profile owner), we have no reason to believe that the app is acting on 13098 // behalf of an enterprise. If the app set the install reason to enterprise policy, 13099 // change it to unknown instead. 13100 return PackageManager.INSTALL_REASON_UNKNOWN; 13101 } 13102 13103 // If the install is being performed by a regular app and the install reason was set to any 13104 // value but enterprise policy, leave the install reason unchanged. 13105 return installReason; 13106 } 13107 13108 void installStage(String packageName, File stagedDir, String stagedCid, 13109 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 13110 String installerPackageName, int installerUid, UserHandle user, 13111 Certificate[][] certificates) { 13112 if (DEBUG_EPHEMERAL) { 13113 if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { 13114 Slog.d(TAG, "Ephemeral install of " + packageName); 13115 } 13116 } 13117 final VerificationInfo verificationInfo = new VerificationInfo( 13118 sessionParams.originatingUri, sessionParams.referrerUri, 13119 sessionParams.originatingUid, installerUid); 13120 13121 final OriginInfo origin; 13122 if (stagedDir != null) { 13123 origin = OriginInfo.fromStagedFile(stagedDir); 13124 } else { 13125 origin = OriginInfo.fromStagedContainer(stagedCid); 13126 } 13127 13128 final Message msg = mHandler.obtainMessage(INIT_COPY); 13129 final int installReason = fixUpInstallReason(installerPackageName, installerUid, 13130 sessionParams.installReason); 13131 final InstallParams params = new InstallParams(origin, null, observer, 13132 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 13133 verificationInfo, user, sessionParams.abiOverride, 13134 sessionParams.grantedRuntimePermissions, certificates, installReason); 13135 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 13136 msg.obj = params; 13137 13138 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 13139 System.identityHashCode(msg.obj)); 13140 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 13141 System.identityHashCode(msg.obj)); 13142 13143 mHandler.sendMessage(msg); 13144 } 13145 13146 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 13147 int userId) { 13148 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 13149 sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId); 13150 } 13151 13152 private void sendPackageAddedForNewUsers(String packageName, boolean isSystem, 13153 int appId, int... userIds) { 13154 if (ArrayUtils.isEmpty(userIds)) { 13155 return; 13156 } 13157 Bundle extras = new Bundle(1); 13158 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast 13159 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId)); 13160 13161 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 13162 packageName, extras, 0, null, null, userIds); 13163 if (isSystem) { 13164 mHandler.post(() -> { 13165 for (int userId : userIds) { 13166 sendBootCompletedBroadcastToSystemApp(packageName, userId); 13167 } 13168 } 13169 ); 13170 } 13171 } 13172 13173 /** 13174 * The just-installed/enabled app is bundled on the system, so presumed to be able to run 13175 * automatically without needing an explicit launch. 13176 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones. 13177 */ 13178 private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) { 13179 // If user is not running, the app didn't miss any broadcast 13180 if (!mUserManagerInternal.isUserRunning(userId)) { 13181 return; 13182 } 13183 final IActivityManager am = ActivityManager.getService(); 13184 try { 13185 // Deliver LOCKED_BOOT_COMPLETED first 13186 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED) 13187 .setPackage(packageName); 13188 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED}; 13189 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions, 13190 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 13191 13192 // Deliver BOOT_COMPLETED only if user is unlocked 13193 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) { 13194 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName); 13195 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions, 13196 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 13197 } 13198 } catch (RemoteException e) { 13199 throw e.rethrowFromSystemServer(); 13200 } 13201 } 13202 13203 @Override 13204 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 13205 int userId) { 13206 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13207 PackageSetting pkgSetting; 13208 final int uid = Binder.getCallingUid(); 13209 enforceCrossUserPermission(uid, userId, 13210 true /* requireFullPermission */, true /* checkShell */, 13211 "setApplicationHiddenSetting for user " + userId); 13212 13213 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 13214 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 13215 return false; 13216 } 13217 13218 long callingId = Binder.clearCallingIdentity(); 13219 try { 13220 boolean sendAdded = false; 13221 boolean sendRemoved = false; 13222 // writer 13223 synchronized (mPackages) { 13224 pkgSetting = mSettings.mPackages.get(packageName); 13225 if (pkgSetting == null) { 13226 return false; 13227 } 13228 // Do not allow "android" is being disabled 13229 if ("android".equals(packageName)) { 13230 Slog.w(TAG, "Cannot hide package: android"); 13231 return false; 13232 } 13233 // Cannot hide static shared libs as they are considered 13234 // a part of the using app (emulating static linking). Also 13235 // static libs are installed always on internal storage. 13236 PackageParser.Package pkg = mPackages.get(packageName); 13237 if (pkg != null && pkg.staticSharedLibName != null) { 13238 Slog.w(TAG, "Cannot hide package: " + packageName 13239 + " providing static shared library: " 13240 + pkg.staticSharedLibName); 13241 return false; 13242 } 13243 // Only allow protected packages to hide themselves. 13244 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 13245 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 13246 Slog.w(TAG, "Not hiding protected package: " + packageName); 13247 return false; 13248 } 13249 13250 if (pkgSetting.getHidden(userId) != hidden) { 13251 pkgSetting.setHidden(hidden, userId); 13252 mSettings.writePackageRestrictionsLPr(userId); 13253 if (hidden) { 13254 sendRemoved = true; 13255 } else { 13256 sendAdded = true; 13257 } 13258 } 13259 } 13260 if (sendAdded) { 13261 sendPackageAddedForUser(packageName, pkgSetting, userId); 13262 return true; 13263 } 13264 if (sendRemoved) { 13265 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 13266 "hiding pkg"); 13267 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 13268 return true; 13269 } 13270 } finally { 13271 Binder.restoreCallingIdentity(callingId); 13272 } 13273 return false; 13274 } 13275 13276 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 13277 int userId) { 13278 final PackageRemovedInfo info = new PackageRemovedInfo(); 13279 info.removedPackage = packageName; 13280 info.removedUsers = new int[] {userId}; 13281 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 13282 info.sendPackageRemovedBroadcasts(true /*killApp*/); 13283 } 13284 13285 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 13286 if (pkgList.length > 0) { 13287 Bundle extras = new Bundle(1); 13288 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 13289 13290 sendPackageBroadcast( 13291 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 13292 : Intent.ACTION_PACKAGES_UNSUSPENDED, 13293 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 13294 new int[] {userId}); 13295 } 13296 } 13297 13298 /** 13299 * Returns true if application is not found or there was an error. Otherwise it returns 13300 * the hidden state of the package for the given user. 13301 */ 13302 @Override 13303 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 13304 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13305 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13306 true /* requireFullPermission */, false /* checkShell */, 13307 "getApplicationHidden for user " + userId); 13308 PackageSetting pkgSetting; 13309 long callingId = Binder.clearCallingIdentity(); 13310 try { 13311 // writer 13312 synchronized (mPackages) { 13313 pkgSetting = mSettings.mPackages.get(packageName); 13314 if (pkgSetting == null) { 13315 return true; 13316 } 13317 return pkgSetting.getHidden(userId); 13318 } 13319 } finally { 13320 Binder.restoreCallingIdentity(callingId); 13321 } 13322 } 13323 13324 /** 13325 * @hide 13326 */ 13327 @Override 13328 public int installExistingPackageAsUser(String packageName, int userId, int installFlags, 13329 int installReason) { 13330 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 13331 null); 13332 PackageSetting pkgSetting; 13333 final int uid = Binder.getCallingUid(); 13334 enforceCrossUserPermission(uid, userId, 13335 true /* requireFullPermission */, true /* checkShell */, 13336 "installExistingPackage for user " + userId); 13337 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 13338 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 13339 } 13340 13341 long callingId = Binder.clearCallingIdentity(); 13342 try { 13343 boolean installed = false; 13344 final boolean instantApp = 13345 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 13346 final boolean fullApp = 13347 (installFlags & PackageManager.INSTALL_FULL_APP) != 0; 13348 13349 // writer 13350 synchronized (mPackages) { 13351 pkgSetting = mSettings.mPackages.get(packageName); 13352 if (pkgSetting == null) { 13353 return PackageManager.INSTALL_FAILED_INVALID_URI; 13354 } 13355 if (!pkgSetting.getInstalled(userId)) { 13356 pkgSetting.setInstalled(true, userId); 13357 pkgSetting.setHidden(false, userId); 13358 pkgSetting.setInstallReason(installReason, userId); 13359 mSettings.writePackageRestrictionsLPr(userId); 13360 mSettings.writeKernelMappingLPr(pkgSetting); 13361 installed = true; 13362 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 13363 // upgrade app from instant to full; we don't allow app downgrade 13364 installed = true; 13365 } 13366 setInstantAppForUser(pkgSetting, userId, instantApp, fullApp); 13367 } 13368 13369 if (installed) { 13370 if (pkgSetting.pkg != null) { 13371 synchronized (mInstallLock) { 13372 // We don't need to freeze for a brand new install 13373 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 13374 } 13375 } 13376 sendPackageAddedForUser(packageName, pkgSetting, userId); 13377 synchronized (mPackages) { 13378 updateSequenceNumberLP(packageName, new int[]{ userId }); 13379 } 13380 } 13381 } finally { 13382 Binder.restoreCallingIdentity(callingId); 13383 } 13384 13385 return PackageManager.INSTALL_SUCCEEDED; 13386 } 13387 13388 void setInstantAppForUser(PackageSetting pkgSetting, int userId, 13389 boolean instantApp, boolean fullApp) { 13390 // no state specified; do nothing 13391 if (!instantApp && !fullApp) { 13392 return; 13393 } 13394 if (userId != UserHandle.USER_ALL) { 13395 if (instantApp && !pkgSetting.getInstantApp(userId)) { 13396 pkgSetting.setInstantApp(true /*instantApp*/, userId); 13397 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 13398 pkgSetting.setInstantApp(false /*instantApp*/, userId); 13399 } 13400 } else { 13401 for (int currentUserId : sUserManager.getUserIds()) { 13402 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) { 13403 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId); 13404 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) { 13405 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId); 13406 } 13407 } 13408 } 13409 } 13410 13411 boolean isUserRestricted(int userId, String restrictionKey) { 13412 Bundle restrictions = sUserManager.getUserRestrictions(userId); 13413 if (restrictions.getBoolean(restrictionKey, false)) { 13414 Log.w(TAG, "User is restricted: " + restrictionKey); 13415 return true; 13416 } 13417 return false; 13418 } 13419 13420 @Override 13421 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 13422 int userId) { 13423 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 13424 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13425 true /* requireFullPermission */, true /* checkShell */, 13426 "setPackagesSuspended for user " + userId); 13427 13428 if (ArrayUtils.isEmpty(packageNames)) { 13429 return packageNames; 13430 } 13431 13432 // List of package names for whom the suspended state has changed. 13433 List<String> changedPackages = new ArrayList<>(packageNames.length); 13434 // List of package names for whom the suspended state is not set as requested in this 13435 // method. 13436 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 13437 long callingId = Binder.clearCallingIdentity(); 13438 try { 13439 for (int i = 0; i < packageNames.length; i++) { 13440 String packageName = packageNames[i]; 13441 boolean changed = false; 13442 final int appId; 13443 synchronized (mPackages) { 13444 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 13445 if (pkgSetting == null) { 13446 Slog.w(TAG, "Could not find package setting for package \"" + packageName 13447 + "\". Skipping suspending/un-suspending."); 13448 unactionedPackages.add(packageName); 13449 continue; 13450 } 13451 appId = pkgSetting.appId; 13452 if (pkgSetting.getSuspended(userId) != suspended) { 13453 if (!canSuspendPackageForUserLocked(packageName, userId)) { 13454 unactionedPackages.add(packageName); 13455 continue; 13456 } 13457 pkgSetting.setSuspended(suspended, userId); 13458 mSettings.writePackageRestrictionsLPr(userId); 13459 changed = true; 13460 changedPackages.add(packageName); 13461 } 13462 } 13463 13464 if (changed && suspended) { 13465 killApplication(packageName, UserHandle.getUid(userId, appId), 13466 "suspending package"); 13467 } 13468 } 13469 } finally { 13470 Binder.restoreCallingIdentity(callingId); 13471 } 13472 13473 if (!changedPackages.isEmpty()) { 13474 sendPackagesSuspendedForUser(changedPackages.toArray( 13475 new String[changedPackages.size()]), userId, suspended); 13476 } 13477 13478 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 13479 } 13480 13481 @Override 13482 public boolean isPackageSuspendedForUser(String packageName, int userId) { 13483 enforceCrossUserPermission(Binder.getCallingUid(), userId, 13484 true /* requireFullPermission */, false /* checkShell */, 13485 "isPackageSuspendedForUser for user " + userId); 13486 synchronized (mPackages) { 13487 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 13488 if (pkgSetting == null) { 13489 throw new IllegalArgumentException("Unknown target package: " + packageName); 13490 } 13491 return pkgSetting.getSuspended(userId); 13492 } 13493 } 13494 13495 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 13496 if (isPackageDeviceAdmin(packageName, userId)) { 13497 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13498 + "\": has an active device admin"); 13499 return false; 13500 } 13501 13502 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 13503 if (packageName.equals(activeLauncherPackageName)) { 13504 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13505 + "\": contains the active launcher"); 13506 return false; 13507 } 13508 13509 if (packageName.equals(mRequiredInstallerPackage)) { 13510 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13511 + "\": required for package installation"); 13512 return false; 13513 } 13514 13515 if (packageName.equals(mRequiredUninstallerPackage)) { 13516 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13517 + "\": required for package uninstallation"); 13518 return false; 13519 } 13520 13521 if (packageName.equals(mRequiredVerifierPackage)) { 13522 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13523 + "\": required for package verification"); 13524 return false; 13525 } 13526 13527 if (packageName.equals(getDefaultDialerPackageName(userId))) { 13528 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13529 + "\": is the default dialer"); 13530 return false; 13531 } 13532 13533 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 13534 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 13535 + "\": protected package"); 13536 return false; 13537 } 13538 13539 // Cannot suspend static shared libs as they are considered 13540 // a part of the using app (emulating static linking). Also 13541 // static libs are installed always on internal storage. 13542 PackageParser.Package pkg = mPackages.get(packageName); 13543 if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) { 13544 Slog.w(TAG, "Cannot suspend package: " + packageName 13545 + " providing static shared library: " 13546 + pkg.staticSharedLibName); 13547 return false; 13548 } 13549 13550 return true; 13551 } 13552 13553 private String getActiveLauncherPackageName(int userId) { 13554 Intent intent = new Intent(Intent.ACTION_MAIN); 13555 intent.addCategory(Intent.CATEGORY_HOME); 13556 ResolveInfo resolveInfo = resolveIntent( 13557 intent, 13558 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 13559 PackageManager.MATCH_DEFAULT_ONLY, 13560 userId); 13561 13562 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 13563 } 13564 13565 private String getDefaultDialerPackageName(int userId) { 13566 synchronized (mPackages) { 13567 return mSettings.getDefaultDialerPackageNameLPw(userId); 13568 } 13569 } 13570 13571 @Override 13572 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 13573 mContext.enforceCallingOrSelfPermission( 13574 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13575 "Only package verification agents can verify applications"); 13576 13577 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 13578 final PackageVerificationResponse response = new PackageVerificationResponse( 13579 verificationCode, Binder.getCallingUid()); 13580 msg.arg1 = id; 13581 msg.obj = response; 13582 mHandler.sendMessage(msg); 13583 } 13584 13585 @Override 13586 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 13587 long millisecondsToDelay) { 13588 mContext.enforceCallingOrSelfPermission( 13589 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13590 "Only package verification agents can extend verification timeouts"); 13591 13592 final PackageVerificationState state = mPendingVerification.get(id); 13593 final PackageVerificationResponse response = new PackageVerificationResponse( 13594 verificationCodeAtTimeout, Binder.getCallingUid()); 13595 13596 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 13597 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 13598 } 13599 if (millisecondsToDelay < 0) { 13600 millisecondsToDelay = 0; 13601 } 13602 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 13603 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 13604 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 13605 } 13606 13607 if ((state != null) && !state.timeoutExtended()) { 13608 state.extendTimeout(); 13609 13610 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 13611 msg.arg1 = id; 13612 msg.obj = response; 13613 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 13614 } 13615 } 13616 13617 private void broadcastPackageVerified(int verificationId, Uri packageUri, 13618 int verificationCode, UserHandle user) { 13619 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 13620 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 13621 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 13622 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 13623 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 13624 13625 mContext.sendBroadcastAsUser(intent, user, 13626 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 13627 } 13628 13629 private ComponentName matchComponentForVerifier(String packageName, 13630 List<ResolveInfo> receivers) { 13631 ActivityInfo targetReceiver = null; 13632 13633 final int NR = receivers.size(); 13634 for (int i = 0; i < NR; i++) { 13635 final ResolveInfo info = receivers.get(i); 13636 if (info.activityInfo == null) { 13637 continue; 13638 } 13639 13640 if (packageName.equals(info.activityInfo.packageName)) { 13641 targetReceiver = info.activityInfo; 13642 break; 13643 } 13644 } 13645 13646 if (targetReceiver == null) { 13647 return null; 13648 } 13649 13650 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 13651 } 13652 13653 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 13654 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 13655 if (pkgInfo.verifiers.length == 0) { 13656 return null; 13657 } 13658 13659 final int N = pkgInfo.verifiers.length; 13660 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 13661 for (int i = 0; i < N; i++) { 13662 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 13663 13664 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 13665 receivers); 13666 if (comp == null) { 13667 continue; 13668 } 13669 13670 final int verifierUid = getUidForVerifier(verifierInfo); 13671 if (verifierUid == -1) { 13672 continue; 13673 } 13674 13675 if (DEBUG_VERIFY) { 13676 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 13677 + " with the correct signature"); 13678 } 13679 sufficientVerifiers.add(comp); 13680 verificationState.addSufficientVerifier(verifierUid); 13681 } 13682 13683 return sufficientVerifiers; 13684 } 13685 13686 private int getUidForVerifier(VerifierInfo verifierInfo) { 13687 synchronized (mPackages) { 13688 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 13689 if (pkg == null) { 13690 return -1; 13691 } else if (pkg.mSignatures.length != 1) { 13692 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 13693 + " has more than one signature; ignoring"); 13694 return -1; 13695 } 13696 13697 /* 13698 * If the public key of the package's signature does not match 13699 * our expected public key, then this is a different package and 13700 * we should skip. 13701 */ 13702 13703 final byte[] expectedPublicKey; 13704 try { 13705 final Signature verifierSig = pkg.mSignatures[0]; 13706 final PublicKey publicKey = verifierSig.getPublicKey(); 13707 expectedPublicKey = publicKey.getEncoded(); 13708 } catch (CertificateException e) { 13709 return -1; 13710 } 13711 13712 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 13713 13714 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 13715 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 13716 + " does not have the expected public key; ignoring"); 13717 return -1; 13718 } 13719 13720 return pkg.applicationInfo.uid; 13721 } 13722 } 13723 13724 @Override 13725 public void finishPackageInstall(int token, boolean didLaunch) { 13726 enforceSystemOrRoot("Only the system is allowed to finish installs"); 13727 13728 if (DEBUG_INSTALL) { 13729 Slog.v(TAG, "BM finishing package install for " + token); 13730 } 13731 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 13732 13733 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 13734 mHandler.sendMessage(msg); 13735 } 13736 13737 /** 13738 * Get the verification agent timeout. 13739 * 13740 * @return verification timeout in milliseconds 13741 */ 13742 private long getVerificationTimeout() { 13743 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 13744 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 13745 DEFAULT_VERIFICATION_TIMEOUT); 13746 } 13747 13748 /** 13749 * Get the default verification agent response code. 13750 * 13751 * @return default verification response code 13752 */ 13753 private int getDefaultVerificationResponse() { 13754 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13755 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 13756 DEFAULT_VERIFICATION_RESPONSE); 13757 } 13758 13759 /** 13760 * Check whether or not package verification has been enabled. 13761 * 13762 * @return true if verification should be performed 13763 */ 13764 private boolean isVerificationEnabled(int userId, int installFlags) { 13765 if (!DEFAULT_VERIFY_ENABLE) { 13766 return false; 13767 } 13768 13769 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 13770 13771 // Check if installing from ADB 13772 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 13773 // Do not run verification in a test harness environment 13774 if (ActivityManager.isRunningInTestHarness()) { 13775 return false; 13776 } 13777 if (ensureVerifyAppsEnabled) { 13778 return true; 13779 } 13780 // Check if the developer does not want package verification for ADB installs 13781 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13782 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 13783 return false; 13784 } 13785 } 13786 13787 if (ensureVerifyAppsEnabled) { 13788 return true; 13789 } 13790 13791 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13792 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 13793 } 13794 13795 @Override 13796 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 13797 throws RemoteException { 13798 mContext.enforceCallingOrSelfPermission( 13799 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 13800 "Only intentfilter verification agents can verify applications"); 13801 13802 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 13803 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 13804 Binder.getCallingUid(), verificationCode, failedDomains); 13805 msg.arg1 = id; 13806 msg.obj = response; 13807 mHandler.sendMessage(msg); 13808 } 13809 13810 @Override 13811 public int getIntentVerificationStatus(String packageName, int userId) { 13812 synchronized (mPackages) { 13813 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 13814 } 13815 } 13816 13817 @Override 13818 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 13819 mContext.enforceCallingOrSelfPermission( 13820 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13821 13822 boolean result = false; 13823 synchronized (mPackages) { 13824 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 13825 } 13826 if (result) { 13827 scheduleWritePackageRestrictionsLocked(userId); 13828 } 13829 return result; 13830 } 13831 13832 @Override 13833 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 13834 String packageName) { 13835 synchronized (mPackages) { 13836 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 13837 } 13838 } 13839 13840 @Override 13841 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 13842 if (TextUtils.isEmpty(packageName)) { 13843 return ParceledListSlice.emptyList(); 13844 } 13845 synchronized (mPackages) { 13846 PackageParser.Package pkg = mPackages.get(packageName); 13847 if (pkg == null || pkg.activities == null) { 13848 return ParceledListSlice.emptyList(); 13849 } 13850 final int count = pkg.activities.size(); 13851 ArrayList<IntentFilter> result = new ArrayList<>(); 13852 for (int n=0; n<count; n++) { 13853 PackageParser.Activity activity = pkg.activities.get(n); 13854 if (activity.intents != null && activity.intents.size() > 0) { 13855 result.addAll(activity.intents); 13856 } 13857 } 13858 return new ParceledListSlice<>(result); 13859 } 13860 } 13861 13862 @Override 13863 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 13864 mContext.enforceCallingOrSelfPermission( 13865 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 13866 13867 synchronized (mPackages) { 13868 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 13869 if (packageName != null) { 13870 result |= updateIntentVerificationStatus(packageName, 13871 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 13872 userId); 13873 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 13874 packageName, userId); 13875 } 13876 return result; 13877 } 13878 } 13879 13880 @Override 13881 public String getDefaultBrowserPackageName(int userId) { 13882 synchronized (mPackages) { 13883 return mSettings.getDefaultBrowserPackageNameLPw(userId); 13884 } 13885 } 13886 13887 /** 13888 * Get the "allow unknown sources" setting. 13889 * 13890 * @return the current "allow unknown sources" setting 13891 */ 13892 private int getUnknownSourcesSettings() { 13893 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 13894 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 13895 -1); 13896 } 13897 13898 @Override 13899 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 13900 final int uid = Binder.getCallingUid(); 13901 // writer 13902 synchronized (mPackages) { 13903 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 13904 if (targetPackageSetting == null) { 13905 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 13906 } 13907 13908 PackageSetting installerPackageSetting; 13909 if (installerPackageName != null) { 13910 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 13911 if (installerPackageSetting == null) { 13912 throw new IllegalArgumentException("Unknown installer package: " 13913 + installerPackageName); 13914 } 13915 } else { 13916 installerPackageSetting = null; 13917 } 13918 13919 Signature[] callerSignature; 13920 Object obj = mSettings.getUserIdLPr(uid); 13921 if (obj != null) { 13922 if (obj instanceof SharedUserSetting) { 13923 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 13924 } else if (obj instanceof PackageSetting) { 13925 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 13926 } else { 13927 throw new SecurityException("Bad object " + obj + " for uid " + uid); 13928 } 13929 } else { 13930 throw new SecurityException("Unknown calling UID: " + uid); 13931 } 13932 13933 // Verify: can't set installerPackageName to a package that is 13934 // not signed with the same cert as the caller. 13935 if (installerPackageSetting != null) { 13936 if (compareSignatures(callerSignature, 13937 installerPackageSetting.signatures.mSignatures) 13938 != PackageManager.SIGNATURE_MATCH) { 13939 throw new SecurityException( 13940 "Caller does not have same cert as new installer package " 13941 + installerPackageName); 13942 } 13943 } 13944 13945 // Verify: if target already has an installer package, it must 13946 // be signed with the same cert as the caller. 13947 if (targetPackageSetting.installerPackageName != null) { 13948 PackageSetting setting = mSettings.mPackages.get( 13949 targetPackageSetting.installerPackageName); 13950 // If the currently set package isn't valid, then it's always 13951 // okay to change it. 13952 if (setting != null) { 13953 if (compareSignatures(callerSignature, 13954 setting.signatures.mSignatures) 13955 != PackageManager.SIGNATURE_MATCH) { 13956 throw new SecurityException( 13957 "Caller does not have same cert as old installer package " 13958 + targetPackageSetting.installerPackageName); 13959 } 13960 } 13961 } 13962 13963 // Okay! 13964 targetPackageSetting.installerPackageName = installerPackageName; 13965 if (installerPackageName != null) { 13966 mSettings.mInstallerPackages.add(installerPackageName); 13967 } 13968 scheduleWriteSettingsLocked(); 13969 } 13970 } 13971 13972 @Override 13973 public void setApplicationCategoryHint(String packageName, int categoryHint, 13974 String callerPackageName) { 13975 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), 13976 callerPackageName); 13977 synchronized (mPackages) { 13978 PackageSetting ps = mSettings.mPackages.get(packageName); 13979 if (ps == null) { 13980 throw new IllegalArgumentException("Unknown target package " + packageName); 13981 } 13982 13983 if (!Objects.equals(callerPackageName, ps.installerPackageName)) { 13984 throw new IllegalArgumentException("Calling package " + callerPackageName 13985 + " is not installer for " + packageName); 13986 } 13987 13988 if (ps.categoryHint != categoryHint) { 13989 ps.categoryHint = categoryHint; 13990 scheduleWriteSettingsLocked(); 13991 } 13992 } 13993 } 13994 13995 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 13996 // Queue up an async operation since the package installation may take a little while. 13997 mHandler.post(new Runnable() { 13998 public void run() { 13999 mHandler.removeCallbacks(this); 14000 // Result object to be returned 14001 PackageInstalledInfo res = new PackageInstalledInfo(); 14002 res.setReturnCode(currentStatus); 14003 res.uid = -1; 14004 res.pkg = null; 14005 res.removedInfo = null; 14006 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14007 args.doPreInstall(res.returnCode); 14008 synchronized (mInstallLock) { 14009 installPackageTracedLI(args, res); 14010 } 14011 args.doPostInstall(res.returnCode, res.uid); 14012 } 14013 14014 // A restore should be performed at this point if (a) the install 14015 // succeeded, (b) the operation is not an update, and (c) the new 14016 // package has not opted out of backup participation. 14017 final boolean update = res.removedInfo != null 14018 && res.removedInfo.removedPackage != null; 14019 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 14020 boolean doRestore = !update 14021 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 14022 14023 // Set up the post-install work request bookkeeping. This will be used 14024 // and cleaned up by the post-install event handling regardless of whether 14025 // there's a restore pass performed. Token values are >= 1. 14026 int token; 14027 if (mNextInstallToken < 0) mNextInstallToken = 1; 14028 token = mNextInstallToken++; 14029 14030 PostInstallData data = new PostInstallData(args, res); 14031 mRunningInstalls.put(token, data); 14032 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 14033 14034 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 14035 // Pass responsibility to the Backup Manager. It will perform a 14036 // restore if appropriate, then pass responsibility back to the 14037 // Package Manager to run the post-install observer callbacks 14038 // and broadcasts. 14039 IBackupManager bm = IBackupManager.Stub.asInterface( 14040 ServiceManager.getService(Context.BACKUP_SERVICE)); 14041 if (bm != null) { 14042 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 14043 + " to BM for possible restore"); 14044 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 14045 try { 14046 // TODO: http://b/22388012 14047 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 14048 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 14049 } else { 14050 doRestore = false; 14051 } 14052 } catch (RemoteException e) { 14053 // can't happen; the backup manager is local 14054 } catch (Exception e) { 14055 Slog.e(TAG, "Exception trying to enqueue restore", e); 14056 doRestore = false; 14057 } 14058 } else { 14059 Slog.e(TAG, "Backup Manager not found!"); 14060 doRestore = false; 14061 } 14062 } 14063 14064 if (!doRestore) { 14065 // No restore possible, or the Backup Manager was mysteriously not 14066 // available -- just fire the post-install work request directly. 14067 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 14068 14069 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 14070 14071 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 14072 mHandler.sendMessage(msg); 14073 } 14074 } 14075 }); 14076 } 14077 14078 /** 14079 * Callback from PackageSettings whenever an app is first transitioned out of the 14080 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 14081 * the app was "launched" for a restoreAtInstall operation. Therefore we check 14082 * here whether the app is the target of an ongoing install, and only send the 14083 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 14084 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 14085 * handling. 14086 */ 14087 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 14088 // Serialize this with the rest of the install-process message chain. In the 14089 // restore-at-install case, this Runnable will necessarily run before the 14090 // POST_INSTALL message is processed, so the contents of mRunningInstalls 14091 // are coherent. In the non-restore case, the app has already completed install 14092 // and been launched through some other means, so it is not in a problematic 14093 // state for observers to see the FIRST_LAUNCH signal. 14094 mHandler.post(new Runnable() { 14095 @Override 14096 public void run() { 14097 for (int i = 0; i < mRunningInstalls.size(); i++) { 14098 final PostInstallData data = mRunningInstalls.valueAt(i); 14099 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14100 continue; 14101 } 14102 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 14103 // right package; but is it for the right user? 14104 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 14105 if (userId == data.res.newUsers[uIndex]) { 14106 if (DEBUG_BACKUP) { 14107 Slog.i(TAG, "Package " + pkgName 14108 + " being restored so deferring FIRST_LAUNCH"); 14109 } 14110 return; 14111 } 14112 } 14113 } 14114 } 14115 // didn't find it, so not being restored 14116 if (DEBUG_BACKUP) { 14117 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 14118 } 14119 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 14120 } 14121 }); 14122 } 14123 14124 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 14125 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 14126 installerPkg, null, userIds); 14127 } 14128 14129 private abstract class HandlerParams { 14130 private static final int MAX_RETRIES = 4; 14131 14132 /** 14133 * Number of times startCopy() has been attempted and had a non-fatal 14134 * error. 14135 */ 14136 private int mRetries = 0; 14137 14138 /** User handle for the user requesting the information or installation. */ 14139 private final UserHandle mUser; 14140 String traceMethod; 14141 int traceCookie; 14142 14143 HandlerParams(UserHandle user) { 14144 mUser = user; 14145 } 14146 14147 UserHandle getUser() { 14148 return mUser; 14149 } 14150 14151 HandlerParams setTraceMethod(String traceMethod) { 14152 this.traceMethod = traceMethod; 14153 return this; 14154 } 14155 14156 HandlerParams setTraceCookie(int traceCookie) { 14157 this.traceCookie = traceCookie; 14158 return this; 14159 } 14160 14161 final boolean startCopy() { 14162 boolean res; 14163 try { 14164 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 14165 14166 if (++mRetries > MAX_RETRIES) { 14167 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 14168 mHandler.sendEmptyMessage(MCS_GIVE_UP); 14169 handleServiceError(); 14170 return false; 14171 } else { 14172 handleStartCopy(); 14173 res = true; 14174 } 14175 } catch (RemoteException e) { 14176 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 14177 mHandler.sendEmptyMessage(MCS_RECONNECT); 14178 res = false; 14179 } 14180 handleReturnCode(); 14181 return res; 14182 } 14183 14184 final void serviceError() { 14185 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 14186 handleServiceError(); 14187 handleReturnCode(); 14188 } 14189 14190 abstract void handleStartCopy() throws RemoteException; 14191 abstract void handleServiceError(); 14192 abstract void handleReturnCode(); 14193 } 14194 14195 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 14196 for (File path : paths) { 14197 try { 14198 mcs.clearDirectory(path.getAbsolutePath()); 14199 } catch (RemoteException e) { 14200 } 14201 } 14202 } 14203 14204 static class OriginInfo { 14205 /** 14206 * Location where install is coming from, before it has been 14207 * copied/renamed into place. This could be a single monolithic APK 14208 * file, or a cluster directory. This location may be untrusted. 14209 */ 14210 final File file; 14211 final String cid; 14212 14213 /** 14214 * Flag indicating that {@link #file} or {@link #cid} has already been 14215 * staged, meaning downstream users don't need to defensively copy the 14216 * contents. 14217 */ 14218 final boolean staged; 14219 14220 /** 14221 * Flag indicating that {@link #file} or {@link #cid} is an already 14222 * installed app that is being moved. 14223 */ 14224 final boolean existing; 14225 14226 final String resolvedPath; 14227 final File resolvedFile; 14228 14229 static OriginInfo fromNothing() { 14230 return new OriginInfo(null, null, false, false); 14231 } 14232 14233 static OriginInfo fromUntrustedFile(File file) { 14234 return new OriginInfo(file, null, false, false); 14235 } 14236 14237 static OriginInfo fromExistingFile(File file) { 14238 return new OriginInfo(file, null, false, true); 14239 } 14240 14241 static OriginInfo fromStagedFile(File file) { 14242 return new OriginInfo(file, null, true, false); 14243 } 14244 14245 static OriginInfo fromStagedContainer(String cid) { 14246 return new OriginInfo(null, cid, true, false); 14247 } 14248 14249 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 14250 this.file = file; 14251 this.cid = cid; 14252 this.staged = staged; 14253 this.existing = existing; 14254 14255 if (cid != null) { 14256 resolvedPath = PackageHelper.getSdDir(cid); 14257 resolvedFile = new File(resolvedPath); 14258 } else if (file != null) { 14259 resolvedPath = file.getAbsolutePath(); 14260 resolvedFile = file; 14261 } else { 14262 resolvedPath = null; 14263 resolvedFile = null; 14264 } 14265 } 14266 } 14267 14268 static class MoveInfo { 14269 final int moveId; 14270 final String fromUuid; 14271 final String toUuid; 14272 final String packageName; 14273 final String dataAppName; 14274 final int appId; 14275 final String seinfo; 14276 final int targetSdkVersion; 14277 14278 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 14279 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 14280 this.moveId = moveId; 14281 this.fromUuid = fromUuid; 14282 this.toUuid = toUuid; 14283 this.packageName = packageName; 14284 this.dataAppName = dataAppName; 14285 this.appId = appId; 14286 this.seinfo = seinfo; 14287 this.targetSdkVersion = targetSdkVersion; 14288 } 14289 } 14290 14291 static class VerificationInfo { 14292 /** A constant used to indicate that a uid value is not present. */ 14293 public static final int NO_UID = -1; 14294 14295 /** URI referencing where the package was downloaded from. */ 14296 final Uri originatingUri; 14297 14298 /** HTTP referrer URI associated with the originatingURI. */ 14299 final Uri referrer; 14300 14301 /** UID of the application that the install request originated from. */ 14302 final int originatingUid; 14303 14304 /** UID of application requesting the install */ 14305 final int installerUid; 14306 14307 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 14308 this.originatingUri = originatingUri; 14309 this.referrer = referrer; 14310 this.originatingUid = originatingUid; 14311 this.installerUid = installerUid; 14312 } 14313 } 14314 14315 class InstallParams extends HandlerParams { 14316 final OriginInfo origin; 14317 final MoveInfo move; 14318 final IPackageInstallObserver2 observer; 14319 int installFlags; 14320 final String installerPackageName; 14321 final String volumeUuid; 14322 private InstallArgs mArgs; 14323 private int mRet; 14324 final String packageAbiOverride; 14325 final String[] grantedRuntimePermissions; 14326 final VerificationInfo verificationInfo; 14327 final Certificate[][] certificates; 14328 final int installReason; 14329 14330 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 14331 int installFlags, String installerPackageName, String volumeUuid, 14332 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 14333 String[] grantedPermissions, Certificate[][] certificates, int installReason) { 14334 super(user); 14335 this.origin = origin; 14336 this.move = move; 14337 this.observer = observer; 14338 this.installFlags = installFlags; 14339 this.installerPackageName = installerPackageName; 14340 this.volumeUuid = volumeUuid; 14341 this.verificationInfo = verificationInfo; 14342 this.packageAbiOverride = packageAbiOverride; 14343 this.grantedRuntimePermissions = grantedPermissions; 14344 this.certificates = certificates; 14345 this.installReason = installReason; 14346 } 14347 14348 @Override 14349 public String toString() { 14350 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 14351 + " file=" + origin.file + " cid=" + origin.cid + "}"; 14352 } 14353 14354 private int installLocationPolicy(PackageInfoLite pkgLite) { 14355 String packageName = pkgLite.packageName; 14356 int installLocation = pkgLite.installLocation; 14357 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14358 // reader 14359 synchronized (mPackages) { 14360 // Currently installed package which the new package is attempting to replace or 14361 // null if no such package is installed. 14362 PackageParser.Package installedPkg = mPackages.get(packageName); 14363 // Package which currently owns the data which the new package will own if installed. 14364 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 14365 // will be null whereas dataOwnerPkg will contain information about the package 14366 // which was uninstalled while keeping its data. 14367 PackageParser.Package dataOwnerPkg = installedPkg; 14368 if (dataOwnerPkg == null) { 14369 PackageSetting ps = mSettings.mPackages.get(packageName); 14370 if (ps != null) { 14371 dataOwnerPkg = ps.pkg; 14372 } 14373 } 14374 14375 if (dataOwnerPkg != null) { 14376 // If installed, the package will get access to data left on the device by its 14377 // predecessor. As a security measure, this is permited only if this is not a 14378 // version downgrade or if the predecessor package is marked as debuggable and 14379 // a downgrade is explicitly requested. 14380 // 14381 // On debuggable platform builds, downgrades are permitted even for 14382 // non-debuggable packages to make testing easier. Debuggable platform builds do 14383 // not offer security guarantees and thus it's OK to disable some security 14384 // mechanisms to make debugging/testing easier on those builds. However, even on 14385 // debuggable builds downgrades of packages are permitted only if requested via 14386 // installFlags. This is because we aim to keep the behavior of debuggable 14387 // platform builds as close as possible to the behavior of non-debuggable 14388 // platform builds. 14389 final boolean downgradeRequested = 14390 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 14391 final boolean packageDebuggable = 14392 (dataOwnerPkg.applicationInfo.flags 14393 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 14394 final boolean downgradePermitted = 14395 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 14396 if (!downgradePermitted) { 14397 try { 14398 checkDowngrade(dataOwnerPkg, pkgLite); 14399 } catch (PackageManagerException e) { 14400 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 14401 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 14402 } 14403 } 14404 } 14405 14406 if (installedPkg != null) { 14407 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 14408 // Check for updated system application. 14409 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14410 if (onSd) { 14411 Slog.w(TAG, "Cannot install update to system app on sdcard"); 14412 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 14413 } 14414 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14415 } else { 14416 if (onSd) { 14417 // Install flag overrides everything. 14418 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14419 } 14420 // If current upgrade specifies particular preference 14421 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 14422 // Application explicitly specified internal. 14423 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14424 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 14425 // App explictly prefers external. Let policy decide 14426 } else { 14427 // Prefer previous location 14428 if (isExternal(installedPkg)) { 14429 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14430 } 14431 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 14432 } 14433 } 14434 } else { 14435 // Invalid install. Return error code 14436 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 14437 } 14438 } 14439 } 14440 // All the special cases have been taken care of. 14441 // Return result based on recommended install location. 14442 if (onSd) { 14443 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 14444 } 14445 return pkgLite.recommendedInstallLocation; 14446 } 14447 14448 /* 14449 * Invoke remote method to get package information and install 14450 * location values. Override install location based on default 14451 * policy if needed and then create install arguments based 14452 * on the install location. 14453 */ 14454 public void handleStartCopy() throws RemoteException { 14455 int ret = PackageManager.INSTALL_SUCCEEDED; 14456 14457 // If we're already staged, we've firmly committed to an install location 14458 if (origin.staged) { 14459 if (origin.file != null) { 14460 installFlags |= PackageManager.INSTALL_INTERNAL; 14461 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 14462 } else if (origin.cid != null) { 14463 installFlags |= PackageManager.INSTALL_EXTERNAL; 14464 installFlags &= ~PackageManager.INSTALL_INTERNAL; 14465 } else { 14466 throw new IllegalStateException("Invalid stage location"); 14467 } 14468 } 14469 14470 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14471 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 14472 final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14473 PackageInfoLite pkgLite = null; 14474 14475 if (onInt && onSd) { 14476 // Check if both bits are set. 14477 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 14478 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14479 } else if (onSd && ephemeral) { 14480 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 14481 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14482 } else { 14483 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 14484 packageAbiOverride); 14485 14486 if (DEBUG_EPHEMERAL && ephemeral) { 14487 Slog.v(TAG, "pkgLite for install: " + pkgLite); 14488 } 14489 14490 /* 14491 * If we have too little free space, try to free cache 14492 * before giving up. 14493 */ 14494 if (!origin.staged && pkgLite.recommendedInstallLocation 14495 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 14496 // TODO: focus freeing disk space on the target device 14497 final StorageManager storage = StorageManager.from(mContext); 14498 final long lowThreshold = storage.getStorageLowBytes( 14499 Environment.getDataDirectory()); 14500 14501 final long sizeBytes = mContainerService.calculateInstalledSize( 14502 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 14503 14504 try { 14505 mInstaller.freeCache(null, sizeBytes + lowThreshold, 0); 14506 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 14507 installFlags, packageAbiOverride); 14508 } catch (InstallerException e) { 14509 Slog.w(TAG, "Failed to free cache", e); 14510 } 14511 14512 /* 14513 * The cache free must have deleted the file we 14514 * downloaded to install. 14515 * 14516 * TODO: fix the "freeCache" call to not delete 14517 * the file we care about. 14518 */ 14519 if (pkgLite.recommendedInstallLocation 14520 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 14521 pkgLite.recommendedInstallLocation 14522 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 14523 } 14524 } 14525 } 14526 14527 if (ret == PackageManager.INSTALL_SUCCEEDED) { 14528 int loc = pkgLite.recommendedInstallLocation; 14529 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 14530 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 14531 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 14532 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 14533 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 14534 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 14535 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 14536 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 14537 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 14538 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 14539 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 14540 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 14541 } else { 14542 // Override with defaults if needed. 14543 loc = installLocationPolicy(pkgLite); 14544 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 14545 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 14546 } else if (!onSd && !onInt) { 14547 // Override install location with flags 14548 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 14549 // Set the flag to install on external media. 14550 installFlags |= PackageManager.INSTALL_EXTERNAL; 14551 installFlags &= ~PackageManager.INSTALL_INTERNAL; 14552 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 14553 if (DEBUG_EPHEMERAL) { 14554 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 14555 } 14556 installFlags |= PackageManager.INSTALL_INSTANT_APP; 14557 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 14558 |PackageManager.INSTALL_INTERNAL); 14559 } else { 14560 // Make sure the flag for installing on external 14561 // media is unset 14562 installFlags |= PackageManager.INSTALL_INTERNAL; 14563 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 14564 } 14565 } 14566 } 14567 } 14568 14569 final InstallArgs args = createInstallArgs(this); 14570 mArgs = args; 14571 14572 if (ret == PackageManager.INSTALL_SUCCEEDED) { 14573 // TODO: http://b/22976637 14574 // Apps installed for "all" users use the device owner to verify the app 14575 UserHandle verifierUser = getUser(); 14576 if (verifierUser == UserHandle.ALL) { 14577 verifierUser = UserHandle.SYSTEM; 14578 } 14579 14580 /* 14581 * Determine if we have any installed package verifiers. If we 14582 * do, then we'll defer to them to verify the packages. 14583 */ 14584 final int requiredUid = mRequiredVerifierPackage == null ? -1 14585 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 14586 verifierUser.getIdentifier()); 14587 if (!origin.existing && requiredUid != -1 14588 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 14589 final Intent verification = new Intent( 14590 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 14591 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14592 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 14593 PACKAGE_MIME_TYPE); 14594 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 14595 14596 // Query all live verifiers based on current user state 14597 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 14598 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 14599 14600 if (DEBUG_VERIFY) { 14601 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 14602 + verification.toString() + " with " + pkgLite.verifiers.length 14603 + " optional verifiers"); 14604 } 14605 14606 final int verificationId = mPendingVerificationToken++; 14607 14608 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 14609 14610 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 14611 installerPackageName); 14612 14613 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 14614 installFlags); 14615 14616 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 14617 pkgLite.packageName); 14618 14619 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 14620 pkgLite.versionCode); 14621 14622 if (verificationInfo != null) { 14623 if (verificationInfo.originatingUri != null) { 14624 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 14625 verificationInfo.originatingUri); 14626 } 14627 if (verificationInfo.referrer != null) { 14628 verification.putExtra(Intent.EXTRA_REFERRER, 14629 verificationInfo.referrer); 14630 } 14631 if (verificationInfo.originatingUid >= 0) { 14632 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 14633 verificationInfo.originatingUid); 14634 } 14635 if (verificationInfo.installerUid >= 0) { 14636 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 14637 verificationInfo.installerUid); 14638 } 14639 } 14640 14641 final PackageVerificationState verificationState = new PackageVerificationState( 14642 requiredUid, args); 14643 14644 mPendingVerification.append(verificationId, verificationState); 14645 14646 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 14647 receivers, verificationState); 14648 14649 DeviceIdleController.LocalService idleController = getDeviceIdleController(); 14650 final long idleDuration = getVerificationTimeout(); 14651 14652 /* 14653 * If any sufficient verifiers were listed in the package 14654 * manifest, attempt to ask them. 14655 */ 14656 if (sufficientVerifiers != null) { 14657 final int N = sufficientVerifiers.size(); 14658 if (N == 0) { 14659 Slog.i(TAG, "Additional verifiers required, but none installed."); 14660 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 14661 } else { 14662 for (int i = 0; i < N; i++) { 14663 final ComponentName verifierComponent = sufficientVerifiers.get(i); 14664 idleController.addPowerSaveTempWhitelistApp(Process.myUid(), 14665 verifierComponent.getPackageName(), idleDuration, 14666 verifierUser.getIdentifier(), false, "package verifier"); 14667 14668 final Intent sufficientIntent = new Intent(verification); 14669 sufficientIntent.setComponent(verifierComponent); 14670 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 14671 } 14672 } 14673 } 14674 14675 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 14676 mRequiredVerifierPackage, receivers); 14677 if (ret == PackageManager.INSTALL_SUCCEEDED 14678 && mRequiredVerifierPackage != null) { 14679 Trace.asyncTraceBegin( 14680 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 14681 /* 14682 * Send the intent to the required verification agent, 14683 * but only start the verification timeout after the 14684 * target BroadcastReceivers have run. 14685 */ 14686 verification.setComponent(requiredVerifierComponent); 14687 idleController.addPowerSaveTempWhitelistApp(Process.myUid(), 14688 mRequiredVerifierPackage, idleDuration, 14689 verifierUser.getIdentifier(), false, "package verifier"); 14690 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 14691 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 14692 new BroadcastReceiver() { 14693 @Override 14694 public void onReceive(Context context, Intent intent) { 14695 final Message msg = mHandler 14696 .obtainMessage(CHECK_PENDING_VERIFICATION); 14697 msg.arg1 = verificationId; 14698 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 14699 } 14700 }, null, 0, null, null); 14701 14702 /* 14703 * We don't want the copy to proceed until verification 14704 * succeeds, so null out this field. 14705 */ 14706 mArgs = null; 14707 } 14708 } else { 14709 /* 14710 * No package verification is enabled, so immediately start 14711 * the remote call to initiate copy using temporary file. 14712 */ 14713 ret = args.copyApk(mContainerService, true); 14714 } 14715 } 14716 14717 mRet = ret; 14718 } 14719 14720 @Override 14721 void handleReturnCode() { 14722 // If mArgs is null, then MCS couldn't be reached. When it 14723 // reconnects, it will try again to install. At that point, this 14724 // will succeed. 14725 if (mArgs != null) { 14726 processPendingInstall(mArgs, mRet); 14727 } 14728 } 14729 14730 @Override 14731 void handleServiceError() { 14732 mArgs = createInstallArgs(this); 14733 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 14734 } 14735 14736 public boolean isForwardLocked() { 14737 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14738 } 14739 } 14740 14741 /** 14742 * Used during creation of InstallArgs 14743 * 14744 * @param installFlags package installation flags 14745 * @return true if should be installed on external storage 14746 */ 14747 private static boolean installOnExternalAsec(int installFlags) { 14748 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 14749 return false; 14750 } 14751 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 14752 return true; 14753 } 14754 return false; 14755 } 14756 14757 /** 14758 * Used during creation of InstallArgs 14759 * 14760 * @param installFlags package installation flags 14761 * @return true if should be installed as forward locked 14762 */ 14763 private static boolean installForwardLocked(int installFlags) { 14764 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14765 } 14766 14767 private InstallArgs createInstallArgs(InstallParams params) { 14768 if (params.move != null) { 14769 return new MoveInstallArgs(params); 14770 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 14771 return new AsecInstallArgs(params); 14772 } else { 14773 return new FileInstallArgs(params); 14774 } 14775 } 14776 14777 /** 14778 * Create args that describe an existing installed package. Typically used 14779 * when cleaning up old installs, or used as a move source. 14780 */ 14781 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 14782 String resourcePath, String[] instructionSets) { 14783 final boolean isInAsec; 14784 if (installOnExternalAsec(installFlags)) { 14785 /* Apps on SD card are always in ASEC containers. */ 14786 isInAsec = true; 14787 } else if (installForwardLocked(installFlags) 14788 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 14789 /* 14790 * Forward-locked apps are only in ASEC containers if they're the 14791 * new style 14792 */ 14793 isInAsec = true; 14794 } else { 14795 isInAsec = false; 14796 } 14797 14798 if (isInAsec) { 14799 return new AsecInstallArgs(codePath, instructionSets, 14800 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 14801 } else { 14802 return new FileInstallArgs(codePath, resourcePath, instructionSets); 14803 } 14804 } 14805 14806 static abstract class InstallArgs { 14807 /** @see InstallParams#origin */ 14808 final OriginInfo origin; 14809 /** @see InstallParams#move */ 14810 final MoveInfo move; 14811 14812 final IPackageInstallObserver2 observer; 14813 // Always refers to PackageManager flags only 14814 final int installFlags; 14815 final String installerPackageName; 14816 final String volumeUuid; 14817 final UserHandle user; 14818 final String abiOverride; 14819 final String[] installGrantPermissions; 14820 /** If non-null, drop an async trace when the install completes */ 14821 final String traceMethod; 14822 final int traceCookie; 14823 final Certificate[][] certificates; 14824 final int installReason; 14825 14826 // The list of instruction sets supported by this app. This is currently 14827 // only used during the rmdex() phase to clean up resources. We can get rid of this 14828 // if we move dex files under the common app path. 14829 /* nullable */ String[] instructionSets; 14830 14831 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 14832 int installFlags, String installerPackageName, String volumeUuid, 14833 UserHandle user, String[] instructionSets, 14834 String abiOverride, String[] installGrantPermissions, 14835 String traceMethod, int traceCookie, Certificate[][] certificates, 14836 int installReason) { 14837 this.origin = origin; 14838 this.move = move; 14839 this.installFlags = installFlags; 14840 this.observer = observer; 14841 this.installerPackageName = installerPackageName; 14842 this.volumeUuid = volumeUuid; 14843 this.user = user; 14844 this.instructionSets = instructionSets; 14845 this.abiOverride = abiOverride; 14846 this.installGrantPermissions = installGrantPermissions; 14847 this.traceMethod = traceMethod; 14848 this.traceCookie = traceCookie; 14849 this.certificates = certificates; 14850 this.installReason = installReason; 14851 } 14852 14853 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 14854 abstract int doPreInstall(int status); 14855 14856 /** 14857 * Rename package into final resting place. All paths on the given 14858 * scanned package should be updated to reflect the rename. 14859 */ 14860 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 14861 abstract int doPostInstall(int status, int uid); 14862 14863 /** @see PackageSettingBase#codePathString */ 14864 abstract String getCodePath(); 14865 /** @see PackageSettingBase#resourcePathString */ 14866 abstract String getResourcePath(); 14867 14868 // Need installer lock especially for dex file removal. 14869 abstract void cleanUpResourcesLI(); 14870 abstract boolean doPostDeleteLI(boolean delete); 14871 14872 /** 14873 * Called before the source arguments are copied. This is used mostly 14874 * for MoveParams when it needs to read the source file to put it in the 14875 * destination. 14876 */ 14877 int doPreCopy() { 14878 return PackageManager.INSTALL_SUCCEEDED; 14879 } 14880 14881 /** 14882 * Called after the source arguments are copied. This is used mostly for 14883 * MoveParams when it needs to read the source file to put it in the 14884 * destination. 14885 */ 14886 int doPostCopy(int uid) { 14887 return PackageManager.INSTALL_SUCCEEDED; 14888 } 14889 14890 protected boolean isFwdLocked() { 14891 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 14892 } 14893 14894 protected boolean isExternalAsec() { 14895 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 14896 } 14897 14898 protected boolean isEphemeral() { 14899 return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14900 } 14901 14902 UserHandle getUser() { 14903 return user; 14904 } 14905 } 14906 14907 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 14908 if (!allCodePaths.isEmpty()) { 14909 if (instructionSets == null) { 14910 throw new IllegalStateException("instructionSet == null"); 14911 } 14912 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 14913 for (String codePath : allCodePaths) { 14914 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 14915 try { 14916 mInstaller.rmdex(codePath, dexCodeInstructionSet); 14917 } catch (InstallerException ignored) { 14918 } 14919 } 14920 } 14921 } 14922 } 14923 14924 /** 14925 * Logic to handle installation of non-ASEC applications, including copying 14926 * and renaming logic. 14927 */ 14928 class FileInstallArgs extends InstallArgs { 14929 private File codeFile; 14930 private File resourceFile; 14931 14932 // Example topology: 14933 // /data/app/com.example/base.apk 14934 // /data/app/com.example/split_foo.apk 14935 // /data/app/com.example/lib/arm/libfoo.so 14936 // /data/app/com.example/lib/arm64/libfoo.so 14937 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 14938 14939 /** New install */ 14940 FileInstallArgs(InstallParams params) { 14941 super(params.origin, params.move, params.observer, params.installFlags, 14942 params.installerPackageName, params.volumeUuid, 14943 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 14944 params.grantedRuntimePermissions, 14945 params.traceMethod, params.traceCookie, params.certificates, 14946 params.installReason); 14947 if (isFwdLocked()) { 14948 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 14949 } 14950 } 14951 14952 /** Existing install */ 14953 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 14954 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 14955 null, null, null, 0, null /*certificates*/, 14956 PackageManager.INSTALL_REASON_UNKNOWN); 14957 this.codeFile = (codePath != null) ? new File(codePath) : null; 14958 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 14959 } 14960 14961 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14962 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 14963 try { 14964 return doCopyApk(imcs, temp); 14965 } finally { 14966 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14967 } 14968 } 14969 14970 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14971 if (origin.staged) { 14972 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 14973 codeFile = origin.file; 14974 resourceFile = origin.file; 14975 return PackageManager.INSTALL_SUCCEEDED; 14976 } 14977 14978 try { 14979 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 14980 final File tempDir = 14981 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 14982 codeFile = tempDir; 14983 resourceFile = tempDir; 14984 } catch (IOException e) { 14985 Slog.w(TAG, "Failed to create copy file: " + e); 14986 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 14987 } 14988 14989 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 14990 @Override 14991 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 14992 if (!FileUtils.isValidExtFilename(name)) { 14993 throw new IllegalArgumentException("Invalid filename: " + name); 14994 } 14995 try { 14996 final File file = new File(codeFile, name); 14997 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 14998 O_RDWR | O_CREAT, 0644); 14999 Os.chmod(file.getAbsolutePath(), 0644); 15000 return new ParcelFileDescriptor(fd); 15001 } catch (ErrnoException e) { 15002 throw new RemoteException("Failed to open: " + e.getMessage()); 15003 } 15004 } 15005 }; 15006 15007 int ret = PackageManager.INSTALL_SUCCEEDED; 15008 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 15009 if (ret != PackageManager.INSTALL_SUCCEEDED) { 15010 Slog.e(TAG, "Failed to copy package"); 15011 return ret; 15012 } 15013 15014 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 15015 NativeLibraryHelper.Handle handle = null; 15016 try { 15017 handle = NativeLibraryHelper.Handle.create(codeFile); 15018 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 15019 abiOverride); 15020 } catch (IOException e) { 15021 Slog.e(TAG, "Copying native libraries failed", e); 15022 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 15023 } finally { 15024 IoUtils.closeQuietly(handle); 15025 } 15026 15027 return ret; 15028 } 15029 15030 int doPreInstall(int status) { 15031 if (status != PackageManager.INSTALL_SUCCEEDED) { 15032 cleanUp(); 15033 } 15034 return status; 15035 } 15036 15037 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15038 if (status != PackageManager.INSTALL_SUCCEEDED) { 15039 cleanUp(); 15040 return false; 15041 } 15042 15043 final File targetDir = codeFile.getParentFile(); 15044 final File beforeCodeFile = codeFile; 15045 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 15046 15047 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 15048 try { 15049 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 15050 } catch (ErrnoException e) { 15051 Slog.w(TAG, "Failed to rename", e); 15052 return false; 15053 } 15054 15055 if (!SELinux.restoreconRecursive(afterCodeFile)) { 15056 Slog.w(TAG, "Failed to restorecon"); 15057 return false; 15058 } 15059 15060 // Reflect the rename internally 15061 codeFile = afterCodeFile; 15062 resourceFile = afterCodeFile; 15063 15064 // Reflect the rename in scanned details 15065 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 15066 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 15067 afterCodeFile, pkg.baseCodePath)); 15068 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 15069 afterCodeFile, pkg.splitCodePaths)); 15070 15071 // Reflect the rename in app info 15072 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15073 pkg.setApplicationInfoCodePath(pkg.codePath); 15074 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15075 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15076 pkg.setApplicationInfoResourcePath(pkg.codePath); 15077 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15078 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15079 15080 return true; 15081 } 15082 15083 int doPostInstall(int status, int uid) { 15084 if (status != PackageManager.INSTALL_SUCCEEDED) { 15085 cleanUp(); 15086 } 15087 return status; 15088 } 15089 15090 @Override 15091 String getCodePath() { 15092 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 15093 } 15094 15095 @Override 15096 String getResourcePath() { 15097 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 15098 } 15099 15100 private boolean cleanUp() { 15101 if (codeFile == null || !codeFile.exists()) { 15102 return false; 15103 } 15104 15105 removeCodePathLI(codeFile); 15106 15107 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 15108 resourceFile.delete(); 15109 } 15110 15111 return true; 15112 } 15113 15114 void cleanUpResourcesLI() { 15115 // Try enumerating all code paths before deleting 15116 List<String> allCodePaths = Collections.EMPTY_LIST; 15117 if (codeFile != null && codeFile.exists()) { 15118 try { 15119 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 15120 allCodePaths = pkg.getAllCodePaths(); 15121 } catch (PackageParserException e) { 15122 // Ignored; we tried our best 15123 } 15124 } 15125 15126 cleanUp(); 15127 removeDexFiles(allCodePaths, instructionSets); 15128 } 15129 15130 boolean doPostDeleteLI(boolean delete) { 15131 // XXX err, shouldn't we respect the delete flag? 15132 cleanUpResourcesLI(); 15133 return true; 15134 } 15135 } 15136 15137 private boolean isAsecExternal(String cid) { 15138 final String asecPath = PackageHelper.getSdFilesystem(cid); 15139 return !asecPath.startsWith(mAsecInternalPath); 15140 } 15141 15142 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 15143 PackageManagerException { 15144 if (copyRet < 0) { 15145 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 15146 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 15147 throw new PackageManagerException(copyRet, message); 15148 } 15149 } 15150 } 15151 15152 /** 15153 * Extract the StorageManagerService "container ID" from the full code path of an 15154 * .apk. 15155 */ 15156 static String cidFromCodePath(String fullCodePath) { 15157 int eidx = fullCodePath.lastIndexOf("/"); 15158 String subStr1 = fullCodePath.substring(0, eidx); 15159 int sidx = subStr1.lastIndexOf("/"); 15160 return subStr1.substring(sidx+1, eidx); 15161 } 15162 15163 /** 15164 * Logic to handle installation of ASEC applications, including copying and 15165 * renaming logic. 15166 */ 15167 class AsecInstallArgs extends InstallArgs { 15168 static final String RES_FILE_NAME = "pkg.apk"; 15169 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 15170 15171 String cid; 15172 String packagePath; 15173 String resourcePath; 15174 15175 /** New install */ 15176 AsecInstallArgs(InstallParams params) { 15177 super(params.origin, params.move, params.observer, params.installFlags, 15178 params.installerPackageName, params.volumeUuid, 15179 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 15180 params.grantedRuntimePermissions, 15181 params.traceMethod, params.traceCookie, params.certificates, 15182 params.installReason); 15183 } 15184 15185 /** Existing install */ 15186 AsecInstallArgs(String fullCodePath, String[] instructionSets, 15187 boolean isExternal, boolean isForwardLocked) { 15188 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 15189 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 15190 instructionSets, null, null, null, 0, null /*certificates*/, 15191 PackageManager.INSTALL_REASON_UNKNOWN); 15192 // Hackily pretend we're still looking at a full code path 15193 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 15194 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 15195 } 15196 15197 // Extract cid from fullCodePath 15198 int eidx = fullCodePath.lastIndexOf("/"); 15199 String subStr1 = fullCodePath.substring(0, eidx); 15200 int sidx = subStr1.lastIndexOf("/"); 15201 cid = subStr1.substring(sidx+1, eidx); 15202 setMountPath(subStr1); 15203 } 15204 15205 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 15206 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 15207 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 15208 instructionSets, null, null, null, 0, null /*certificates*/, 15209 PackageManager.INSTALL_REASON_UNKNOWN); 15210 this.cid = cid; 15211 setMountPath(PackageHelper.getSdDir(cid)); 15212 } 15213 15214 void createCopyFile() { 15215 cid = mInstallerService.allocateExternalStageCidLegacy(); 15216 } 15217 15218 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 15219 if (origin.staged && origin.cid != null) { 15220 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 15221 cid = origin.cid; 15222 setMountPath(PackageHelper.getSdDir(cid)); 15223 return PackageManager.INSTALL_SUCCEEDED; 15224 } 15225 15226 if (temp) { 15227 createCopyFile(); 15228 } else { 15229 /* 15230 * Pre-emptively destroy the container since it's destroyed if 15231 * copying fails due to it existing anyway. 15232 */ 15233 PackageHelper.destroySdDir(cid); 15234 } 15235 15236 final String newMountPath = imcs.copyPackageToContainer( 15237 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 15238 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 15239 15240 if (newMountPath != null) { 15241 setMountPath(newMountPath); 15242 return PackageManager.INSTALL_SUCCEEDED; 15243 } else { 15244 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15245 } 15246 } 15247 15248 @Override 15249 String getCodePath() { 15250 return packagePath; 15251 } 15252 15253 @Override 15254 String getResourcePath() { 15255 return resourcePath; 15256 } 15257 15258 int doPreInstall(int status) { 15259 if (status != PackageManager.INSTALL_SUCCEEDED) { 15260 // Destroy container 15261 PackageHelper.destroySdDir(cid); 15262 } else { 15263 boolean mounted = PackageHelper.isContainerMounted(cid); 15264 if (!mounted) { 15265 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 15266 Process.SYSTEM_UID); 15267 if (newMountPath != null) { 15268 setMountPath(newMountPath); 15269 } else { 15270 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15271 } 15272 } 15273 } 15274 return status; 15275 } 15276 15277 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15278 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 15279 String newMountPath = null; 15280 if (PackageHelper.isContainerMounted(cid)) { 15281 // Unmount the container 15282 if (!PackageHelper.unMountSdDir(cid)) { 15283 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 15284 return false; 15285 } 15286 } 15287 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 15288 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 15289 " which might be stale. Will try to clean up."); 15290 // Clean up the stale container and proceed to recreate. 15291 if (!PackageHelper.destroySdDir(newCacheId)) { 15292 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 15293 return false; 15294 } 15295 // Successfully cleaned up stale container. Try to rename again. 15296 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 15297 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 15298 + " inspite of cleaning it up."); 15299 return false; 15300 } 15301 } 15302 if (!PackageHelper.isContainerMounted(newCacheId)) { 15303 Slog.w(TAG, "Mounting container " + newCacheId); 15304 newMountPath = PackageHelper.mountSdDir(newCacheId, 15305 getEncryptKey(), Process.SYSTEM_UID); 15306 } else { 15307 newMountPath = PackageHelper.getSdDir(newCacheId); 15308 } 15309 if (newMountPath == null) { 15310 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 15311 return false; 15312 } 15313 Log.i(TAG, "Succesfully renamed " + cid + 15314 " to " + newCacheId + 15315 " at new path: " + newMountPath); 15316 cid = newCacheId; 15317 15318 final File beforeCodeFile = new File(packagePath); 15319 setMountPath(newMountPath); 15320 final File afterCodeFile = new File(packagePath); 15321 15322 // Reflect the rename in scanned details 15323 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 15324 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 15325 afterCodeFile, pkg.baseCodePath)); 15326 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 15327 afterCodeFile, pkg.splitCodePaths)); 15328 15329 // Reflect the rename in app info 15330 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15331 pkg.setApplicationInfoCodePath(pkg.codePath); 15332 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15333 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15334 pkg.setApplicationInfoResourcePath(pkg.codePath); 15335 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15336 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15337 15338 return true; 15339 } 15340 15341 private void setMountPath(String mountPath) { 15342 final File mountFile = new File(mountPath); 15343 15344 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 15345 if (monolithicFile.exists()) { 15346 packagePath = monolithicFile.getAbsolutePath(); 15347 if (isFwdLocked()) { 15348 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 15349 } else { 15350 resourcePath = packagePath; 15351 } 15352 } else { 15353 packagePath = mountFile.getAbsolutePath(); 15354 resourcePath = packagePath; 15355 } 15356 } 15357 15358 int doPostInstall(int status, int uid) { 15359 if (status != PackageManager.INSTALL_SUCCEEDED) { 15360 cleanUp(); 15361 } else { 15362 final int groupOwner; 15363 final String protectedFile; 15364 if (isFwdLocked()) { 15365 groupOwner = UserHandle.getSharedAppGid(uid); 15366 protectedFile = RES_FILE_NAME; 15367 } else { 15368 groupOwner = -1; 15369 protectedFile = null; 15370 } 15371 15372 if (uid < Process.FIRST_APPLICATION_UID 15373 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 15374 Slog.e(TAG, "Failed to finalize " + cid); 15375 PackageHelper.destroySdDir(cid); 15376 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15377 } 15378 15379 boolean mounted = PackageHelper.isContainerMounted(cid); 15380 if (!mounted) { 15381 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 15382 } 15383 } 15384 return status; 15385 } 15386 15387 private void cleanUp() { 15388 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 15389 15390 // Destroy secure container 15391 PackageHelper.destroySdDir(cid); 15392 } 15393 15394 private List<String> getAllCodePaths() { 15395 final File codeFile = new File(getCodePath()); 15396 if (codeFile != null && codeFile.exists()) { 15397 try { 15398 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 15399 return pkg.getAllCodePaths(); 15400 } catch (PackageParserException e) { 15401 // Ignored; we tried our best 15402 } 15403 } 15404 return Collections.EMPTY_LIST; 15405 } 15406 15407 void cleanUpResourcesLI() { 15408 // Enumerate all code paths before deleting 15409 cleanUpResourcesLI(getAllCodePaths()); 15410 } 15411 15412 private void cleanUpResourcesLI(List<String> allCodePaths) { 15413 cleanUp(); 15414 removeDexFiles(allCodePaths, instructionSets); 15415 } 15416 15417 String getPackageName() { 15418 return getAsecPackageName(cid); 15419 } 15420 15421 boolean doPostDeleteLI(boolean delete) { 15422 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 15423 final List<String> allCodePaths = getAllCodePaths(); 15424 boolean mounted = PackageHelper.isContainerMounted(cid); 15425 if (mounted) { 15426 // Unmount first 15427 if (PackageHelper.unMountSdDir(cid)) { 15428 mounted = false; 15429 } 15430 } 15431 if (!mounted && delete) { 15432 cleanUpResourcesLI(allCodePaths); 15433 } 15434 return !mounted; 15435 } 15436 15437 @Override 15438 int doPreCopy() { 15439 if (isFwdLocked()) { 15440 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 15441 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 15442 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15443 } 15444 } 15445 15446 return PackageManager.INSTALL_SUCCEEDED; 15447 } 15448 15449 @Override 15450 int doPostCopy(int uid) { 15451 if (isFwdLocked()) { 15452 if (uid < Process.FIRST_APPLICATION_UID 15453 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 15454 RES_FILE_NAME)) { 15455 Slog.e(TAG, "Failed to finalize " + cid); 15456 PackageHelper.destroySdDir(cid); 15457 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 15458 } 15459 } 15460 15461 return PackageManager.INSTALL_SUCCEEDED; 15462 } 15463 } 15464 15465 /** 15466 * Logic to handle movement of existing installed applications. 15467 */ 15468 class MoveInstallArgs extends InstallArgs { 15469 private File codeFile; 15470 private File resourceFile; 15471 15472 /** New install */ 15473 MoveInstallArgs(InstallParams params) { 15474 super(params.origin, params.move, params.observer, params.installFlags, 15475 params.installerPackageName, params.volumeUuid, 15476 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 15477 params.grantedRuntimePermissions, 15478 params.traceMethod, params.traceCookie, params.certificates, 15479 params.installReason); 15480 } 15481 15482 int copyApk(IMediaContainerService imcs, boolean temp) { 15483 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 15484 + move.fromUuid + " to " + move.toUuid); 15485 synchronized (mInstaller) { 15486 try { 15487 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 15488 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 15489 } catch (InstallerException e) { 15490 Slog.w(TAG, "Failed to move app", e); 15491 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 15492 } 15493 } 15494 15495 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 15496 resourceFile = codeFile; 15497 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 15498 15499 return PackageManager.INSTALL_SUCCEEDED; 15500 } 15501 15502 int doPreInstall(int status) { 15503 if (status != PackageManager.INSTALL_SUCCEEDED) { 15504 cleanUp(move.toUuid); 15505 } 15506 return status; 15507 } 15508 15509 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 15510 if (status != PackageManager.INSTALL_SUCCEEDED) { 15511 cleanUp(move.toUuid); 15512 return false; 15513 } 15514 15515 // Reflect the move in app info 15516 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 15517 pkg.setApplicationInfoCodePath(pkg.codePath); 15518 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 15519 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 15520 pkg.setApplicationInfoResourcePath(pkg.codePath); 15521 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 15522 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 15523 15524 return true; 15525 } 15526 15527 int doPostInstall(int status, int uid) { 15528 if (status == PackageManager.INSTALL_SUCCEEDED) { 15529 cleanUp(move.fromUuid); 15530 } else { 15531 cleanUp(move.toUuid); 15532 } 15533 return status; 15534 } 15535 15536 @Override 15537 String getCodePath() { 15538 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 15539 } 15540 15541 @Override 15542 String getResourcePath() { 15543 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 15544 } 15545 15546 private boolean cleanUp(String volumeUuid) { 15547 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 15548 move.dataAppName); 15549 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 15550 final int[] userIds = sUserManager.getUserIds(); 15551 synchronized (mInstallLock) { 15552 // Clean up both app data and code 15553 // All package moves are frozen until finished 15554 for (int userId : userIds) { 15555 try { 15556 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 15557 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 15558 } catch (InstallerException e) { 15559 Slog.w(TAG, String.valueOf(e)); 15560 } 15561 } 15562 removeCodePathLI(codeFile); 15563 } 15564 return true; 15565 } 15566 15567 void cleanUpResourcesLI() { 15568 throw new UnsupportedOperationException(); 15569 } 15570 15571 boolean doPostDeleteLI(boolean delete) { 15572 throw new UnsupportedOperationException(); 15573 } 15574 } 15575 15576 static String getAsecPackageName(String packageCid) { 15577 int idx = packageCid.lastIndexOf("-"); 15578 if (idx == -1) { 15579 return packageCid; 15580 } 15581 return packageCid.substring(0, idx); 15582 } 15583 15584 // Utility method used to create code paths based on package name and available index. 15585 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 15586 String idxStr = ""; 15587 int idx = 1; 15588 // Fall back to default value of idx=1 if prefix is not 15589 // part of oldCodePath 15590 if (oldCodePath != null) { 15591 String subStr = oldCodePath; 15592 // Drop the suffix right away 15593 if (suffix != null && subStr.endsWith(suffix)) { 15594 subStr = subStr.substring(0, subStr.length() - suffix.length()); 15595 } 15596 // If oldCodePath already contains prefix find out the 15597 // ending index to either increment or decrement. 15598 int sidx = subStr.lastIndexOf(prefix); 15599 if (sidx != -1) { 15600 subStr = subStr.substring(sidx + prefix.length()); 15601 if (subStr != null) { 15602 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 15603 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 15604 } 15605 try { 15606 idx = Integer.parseInt(subStr); 15607 if (idx <= 1) { 15608 idx++; 15609 } else { 15610 idx--; 15611 } 15612 } catch(NumberFormatException e) { 15613 } 15614 } 15615 } 15616 } 15617 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 15618 return prefix + idxStr; 15619 } 15620 15621 private File getNextCodePath(File targetDir, String packageName) { 15622 File result; 15623 SecureRandom random = new SecureRandom(); 15624 byte[] bytes = new byte[16]; 15625 do { 15626 random.nextBytes(bytes); 15627 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); 15628 result = new File(targetDir, packageName + "-" + suffix); 15629 } while (result.exists()); 15630 return result; 15631 } 15632 15633 // Utility method that returns the relative package path with respect 15634 // to the installation directory. Like say for /data/data/com.test-1.apk 15635 // string com.test-1 is returned. 15636 static String deriveCodePathName(String codePath) { 15637 if (codePath == null) { 15638 return null; 15639 } 15640 final File codeFile = new File(codePath); 15641 final String name = codeFile.getName(); 15642 if (codeFile.isDirectory()) { 15643 return name; 15644 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 15645 final int lastDot = name.lastIndexOf('.'); 15646 return name.substring(0, lastDot); 15647 } else { 15648 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 15649 return null; 15650 } 15651 } 15652 15653 static class PackageInstalledInfo { 15654 String name; 15655 int uid; 15656 // The set of users that originally had this package installed. 15657 int[] origUsers; 15658 // The set of users that now have this package installed. 15659 int[] newUsers; 15660 PackageParser.Package pkg; 15661 int returnCode; 15662 String returnMsg; 15663 PackageRemovedInfo removedInfo; 15664 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 15665 15666 public void setError(int code, String msg) { 15667 setReturnCode(code); 15668 setReturnMessage(msg); 15669 Slog.w(TAG, msg); 15670 } 15671 15672 public void setError(String msg, PackageParserException e) { 15673 setReturnCode(e.error); 15674 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 15675 Slog.w(TAG, msg, e); 15676 } 15677 15678 public void setError(String msg, PackageManagerException e) { 15679 returnCode = e.error; 15680 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 15681 Slog.w(TAG, msg, e); 15682 } 15683 15684 public void setReturnCode(int returnCode) { 15685 this.returnCode = returnCode; 15686 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 15687 for (int i = 0; i < childCount; i++) { 15688 addedChildPackages.valueAt(i).returnCode = returnCode; 15689 } 15690 } 15691 15692 private void setReturnMessage(String returnMsg) { 15693 this.returnMsg = returnMsg; 15694 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 15695 for (int i = 0; i < childCount; i++) { 15696 addedChildPackages.valueAt(i).returnMsg = returnMsg; 15697 } 15698 } 15699 15700 // In some error cases we want to convey more info back to the observer 15701 String origPackage; 15702 String origPermission; 15703 } 15704 15705 /* 15706 * Install a non-existing package. 15707 */ 15708 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 15709 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 15710 PackageInstalledInfo res, int installReason) { 15711 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 15712 15713 // Remember this for later, in case we need to rollback this install 15714 String pkgName = pkg.packageName; 15715 15716 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 15717 15718 synchronized(mPackages) { 15719 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName); 15720 if (renamedPackage != null) { 15721 // A package with the same name is already installed, though 15722 // it has been renamed to an older name. The package we 15723 // are trying to install should be installed as an update to 15724 // the existing one, but that has not been requested, so bail. 15725 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 15726 + " without first uninstalling package running as " 15727 + renamedPackage); 15728 return; 15729 } 15730 if (mPackages.containsKey(pkgName)) { 15731 // Don't allow installation over an existing package with the same name. 15732 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 15733 + " without first uninstalling."); 15734 return; 15735 } 15736 } 15737 15738 try { 15739 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 15740 System.currentTimeMillis(), user); 15741 15742 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason); 15743 15744 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 15745 prepareAppDataAfterInstallLIF(newPackage); 15746 15747 } else { 15748 // Remove package from internal structures, but keep around any 15749 // data that might have already existed 15750 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 15751 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 15752 } 15753 } catch (PackageManagerException e) { 15754 res.setError("Package couldn't be installed in " + pkg.codePath, e); 15755 } 15756 15757 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15758 } 15759 15760 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 15761 // Can't rotate keys during boot or if sharedUser. 15762 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 15763 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 15764 return false; 15765 } 15766 // app is using upgradeKeySets; make sure all are valid 15767 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15768 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 15769 for (int i = 0; i < upgradeKeySets.length; i++) { 15770 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 15771 Slog.wtf(TAG, "Package " 15772 + (oldPs.name != null ? oldPs.name : "<null>") 15773 + " contains upgrade-key-set reference to unknown key-set: " 15774 + upgradeKeySets[i] 15775 + " reverting to signatures check."); 15776 return false; 15777 } 15778 } 15779 return true; 15780 } 15781 15782 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 15783 // Upgrade keysets are being used. Determine if new package has a superset of the 15784 // required keys. 15785 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 15786 KeySetManagerService ksms = mSettings.mKeySetManagerService; 15787 for (int i = 0; i < upgradeKeySets.length; i++) { 15788 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 15789 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 15790 return true; 15791 } 15792 } 15793 return false; 15794 } 15795 15796 private static void updateDigest(MessageDigest digest, File file) throws IOException { 15797 try (DigestInputStream digestStream = 15798 new DigestInputStream(new FileInputStream(file), digest)) { 15799 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 15800 } 15801 } 15802 15803 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 15804 UserHandle user, String installerPackageName, PackageInstalledInfo res, 15805 int installReason) { 15806 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 15807 15808 final PackageParser.Package oldPackage; 15809 final String pkgName = pkg.packageName; 15810 final int[] allUsers; 15811 final int[] installedUsers; 15812 15813 synchronized(mPackages) { 15814 oldPackage = mPackages.get(pkgName); 15815 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 15816 15817 // don't allow upgrade to target a release SDK from a pre-release SDK 15818 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 15819 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 15820 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 15821 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 15822 if (oldTargetsPreRelease 15823 && !newTargetsPreRelease 15824 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 15825 Slog.w(TAG, "Can't install package targeting released sdk"); 15826 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 15827 return; 15828 } 15829 15830 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15831 15832 // verify signatures are valid 15833 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 15834 if (!checkUpgradeKeySetLP(ps, pkg)) { 15835 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 15836 "New package not signed by keys specified by upgrade-keysets: " 15837 + pkgName); 15838 return; 15839 } 15840 } else { 15841 // default to original signature matching 15842 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 15843 != PackageManager.SIGNATURE_MATCH) { 15844 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 15845 "New package has a different signature: " + pkgName); 15846 return; 15847 } 15848 } 15849 15850 // don't allow a system upgrade unless the upgrade hash matches 15851 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 15852 byte[] digestBytes = null; 15853 try { 15854 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 15855 updateDigest(digest, new File(pkg.baseCodePath)); 15856 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 15857 for (String path : pkg.splitCodePaths) { 15858 updateDigest(digest, new File(path)); 15859 } 15860 } 15861 digestBytes = digest.digest(); 15862 } catch (NoSuchAlgorithmException | IOException e) { 15863 res.setError(INSTALL_FAILED_INVALID_APK, 15864 "Could not compute hash: " + pkgName); 15865 return; 15866 } 15867 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 15868 res.setError(INSTALL_FAILED_INVALID_APK, 15869 "New package fails restrict-update check: " + pkgName); 15870 return; 15871 } 15872 // retain upgrade restriction 15873 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 15874 } 15875 15876 // Check for shared user id changes 15877 String invalidPackageName = 15878 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 15879 if (invalidPackageName != null) { 15880 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 15881 "Package " + invalidPackageName + " tried to change user " 15882 + oldPackage.mSharedUserId); 15883 return; 15884 } 15885 15886 // In case of rollback, remember per-user/profile install state 15887 allUsers = sUserManager.getUserIds(); 15888 installedUsers = ps.queryInstalledUsers(allUsers, true); 15889 15890 // don't allow an upgrade from full to ephemeral 15891 if (isInstantApp) { 15892 if (user == null || user.getIdentifier() == UserHandle.USER_ALL) { 15893 for (int currentUser : allUsers) { 15894 if (!ps.getInstantApp(currentUser)) { 15895 // can't downgrade from full to instant 15896 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName 15897 + " for user: " + currentUser); 15898 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 15899 return; 15900 } 15901 } 15902 } else if (!ps.getInstantApp(user.getIdentifier())) { 15903 // can't downgrade from full to instant 15904 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName 15905 + " for user: " + user.getIdentifier()); 15906 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 15907 return; 15908 } 15909 } 15910 } 15911 15912 // Update what is removed 15913 res.removedInfo = new PackageRemovedInfo(); 15914 res.removedInfo.uid = oldPackage.applicationInfo.uid; 15915 res.removedInfo.removedPackage = oldPackage.packageName; 15916 res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null; 15917 res.removedInfo.isUpdate = true; 15918 res.removedInfo.origUsers = installedUsers; 15919 final PackageSetting ps = mSettings.getPackageLPr(pkgName); 15920 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length); 15921 for (int i = 0; i < installedUsers.length; i++) { 15922 final int userId = installedUsers[i]; 15923 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId)); 15924 } 15925 15926 final int childCount = (oldPackage.childPackages != null) 15927 ? oldPackage.childPackages.size() : 0; 15928 for (int i = 0; i < childCount; i++) { 15929 boolean childPackageUpdated = false; 15930 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 15931 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 15932 if (res.addedChildPackages != null) { 15933 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15934 if (childRes != null) { 15935 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 15936 childRes.removedInfo.removedPackage = childPkg.packageName; 15937 childRes.removedInfo.isUpdate = true; 15938 childRes.removedInfo.installReasons = res.removedInfo.installReasons; 15939 childPackageUpdated = true; 15940 } 15941 } 15942 if (!childPackageUpdated) { 15943 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 15944 childRemovedRes.removedPackage = childPkg.packageName; 15945 childRemovedRes.isUpdate = false; 15946 childRemovedRes.dataRemoved = true; 15947 synchronized (mPackages) { 15948 if (childPs != null) { 15949 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 15950 } 15951 } 15952 if (res.removedInfo.removedChildPackages == null) { 15953 res.removedInfo.removedChildPackages = new ArrayMap<>(); 15954 } 15955 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 15956 } 15957 } 15958 15959 boolean sysPkg = (isSystemApp(oldPackage)); 15960 if (sysPkg) { 15961 // Set the system/privileged flags as needed 15962 final boolean privileged = 15963 (oldPackage.applicationInfo.privateFlags 15964 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15965 final int systemPolicyFlags = policyFlags 15966 | PackageParser.PARSE_IS_SYSTEM 15967 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 15968 15969 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 15970 user, allUsers, installerPackageName, res, installReason); 15971 } else { 15972 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 15973 user, allUsers, installerPackageName, res, installReason); 15974 } 15975 } 15976 15977 public List<String> getPreviousCodePaths(String packageName) { 15978 final PackageSetting ps = mSettings.mPackages.get(packageName); 15979 final List<String> result = new ArrayList<String>(); 15980 if (ps != null && ps.oldCodePaths != null) { 15981 result.addAll(ps.oldCodePaths); 15982 } 15983 return result; 15984 } 15985 15986 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 15987 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 15988 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 15989 int installReason) { 15990 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 15991 + deletedPackage); 15992 15993 String pkgName = deletedPackage.packageName; 15994 boolean deletedPkg = true; 15995 boolean addedPkg = false; 15996 boolean updatedSettings = false; 15997 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 15998 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 15999 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 16000 16001 final long origUpdateTime = (pkg.mExtras != null) 16002 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 16003 16004 // First delete the existing package while retaining the data directory 16005 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 16006 res.removedInfo, true, pkg)) { 16007 // If the existing package wasn't successfully deleted 16008 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 16009 deletedPkg = false; 16010 } else { 16011 // Successfully deleted the old package; proceed with replace. 16012 16013 // If deleted package lived in a container, give users a chance to 16014 // relinquish resources before killing. 16015 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 16016 if (DEBUG_INSTALL) { 16017 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 16018 } 16019 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 16020 final ArrayList<String> pkgList = new ArrayList<String>(1); 16021 pkgList.add(deletedPackage.applicationInfo.packageName); 16022 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 16023 } 16024 16025 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 16026 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16027 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 16028 16029 try { 16030 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 16031 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 16032 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 16033 installReason); 16034 16035 // Update the in-memory copy of the previous code paths. 16036 PackageSetting ps = mSettings.mPackages.get(pkgName); 16037 if (!killApp) { 16038 if (ps.oldCodePaths == null) { 16039 ps.oldCodePaths = new ArraySet<>(); 16040 } 16041 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 16042 if (deletedPackage.splitCodePaths != null) { 16043 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 16044 } 16045 } else { 16046 ps.oldCodePaths = null; 16047 } 16048 if (ps.childPackageNames != null) { 16049 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 16050 final String childPkgName = ps.childPackageNames.get(i); 16051 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 16052 childPs.oldCodePaths = ps.oldCodePaths; 16053 } 16054 } 16055 // set instant app status, but, only if it's explicitly specified 16056 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 16057 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0; 16058 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp); 16059 prepareAppDataAfterInstallLIF(newPackage); 16060 addedPkg = true; 16061 mDexManager.notifyPackageUpdated(newPackage.packageName, 16062 newPackage.baseCodePath, newPackage.splitCodePaths); 16063 } catch (PackageManagerException e) { 16064 res.setError("Package couldn't be installed in " + pkg.codePath, e); 16065 } 16066 } 16067 16068 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 16069 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 16070 16071 // Revert all internal state mutations and added folders for the failed install 16072 if (addedPkg) { 16073 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 16074 res.removedInfo, true, null); 16075 } 16076 16077 // Restore the old package 16078 if (deletedPkg) { 16079 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 16080 File restoreFile = new File(deletedPackage.codePath); 16081 // Parse old package 16082 boolean oldExternal = isExternal(deletedPackage); 16083 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 16084 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 16085 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 16086 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 16087 try { 16088 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 16089 null); 16090 } catch (PackageManagerException e) { 16091 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 16092 + e.getMessage()); 16093 return; 16094 } 16095 16096 synchronized (mPackages) { 16097 // Ensure the installer package name up to date 16098 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 16099 16100 // Update permissions for restored package 16101 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 16102 16103 mSettings.writeLPr(); 16104 } 16105 16106 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 16107 } 16108 } else { 16109 synchronized (mPackages) { 16110 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName); 16111 if (ps != null) { 16112 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16113 if (res.removedInfo.removedChildPackages != null) { 16114 final int childCount = res.removedInfo.removedChildPackages.size(); 16115 // Iterate in reverse as we may modify the collection 16116 for (int i = childCount - 1; i >= 0; i--) { 16117 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 16118 if (res.addedChildPackages.containsKey(childPackageName)) { 16119 res.removedInfo.removedChildPackages.removeAt(i); 16120 } else { 16121 PackageRemovedInfo childInfo = res.removedInfo 16122 .removedChildPackages.valueAt(i); 16123 childInfo.removedForAllUsers = mPackages.get( 16124 childInfo.removedPackage) == null; 16125 } 16126 } 16127 } 16128 } 16129 } 16130 } 16131 } 16132 16133 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 16134 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 16135 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 16136 int installReason) { 16137 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 16138 + ", old=" + deletedPackage); 16139 16140 final boolean disabledSystem; 16141 16142 // Remove existing system package 16143 removePackageLI(deletedPackage, true); 16144 16145 synchronized (mPackages) { 16146 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 16147 } 16148 if (!disabledSystem) { 16149 // We didn't need to disable the .apk as a current system package, 16150 // which means we are replacing another update that is already 16151 // installed. We need to make sure to delete the older one's .apk. 16152 res.removedInfo.args = createInstallArgsForExisting(0, 16153 deletedPackage.applicationInfo.getCodePath(), 16154 deletedPackage.applicationInfo.getResourcePath(), 16155 getAppDexInstructionSets(deletedPackage.applicationInfo)); 16156 } else { 16157 res.removedInfo.args = null; 16158 } 16159 16160 // Successfully disabled the old package. Now proceed with re-installation 16161 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 16162 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16163 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 16164 16165 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16166 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 16167 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 16168 16169 PackageParser.Package newPackage = null; 16170 try { 16171 // Add the package to the internal data structures 16172 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 16173 16174 // Set the update and install times 16175 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 16176 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 16177 System.currentTimeMillis()); 16178 16179 // Update the package dynamic state if succeeded 16180 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 16181 // Now that the install succeeded make sure we remove data 16182 // directories for any child package the update removed. 16183 final int deletedChildCount = (deletedPackage.childPackages != null) 16184 ? deletedPackage.childPackages.size() : 0; 16185 final int newChildCount = (newPackage.childPackages != null) 16186 ? newPackage.childPackages.size() : 0; 16187 for (int i = 0; i < deletedChildCount; i++) { 16188 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 16189 boolean childPackageDeleted = true; 16190 for (int j = 0; j < newChildCount; j++) { 16191 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 16192 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 16193 childPackageDeleted = false; 16194 break; 16195 } 16196 } 16197 if (childPackageDeleted) { 16198 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 16199 deletedChildPkg.packageName); 16200 if (ps != null && res.removedInfo.removedChildPackages != null) { 16201 PackageRemovedInfo removedChildRes = res.removedInfo 16202 .removedChildPackages.get(deletedChildPkg.packageName); 16203 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 16204 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 16205 } 16206 } 16207 } 16208 16209 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 16210 installReason); 16211 prepareAppDataAfterInstallLIF(newPackage); 16212 16213 mDexManager.notifyPackageUpdated(newPackage.packageName, 16214 newPackage.baseCodePath, newPackage.splitCodePaths); 16215 } 16216 } catch (PackageManagerException e) { 16217 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 16218 res.setError("Package couldn't be installed in " + pkg.codePath, e); 16219 } 16220 16221 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 16222 // Re installation failed. Restore old information 16223 // Remove new pkg information 16224 if (newPackage != null) { 16225 removeInstalledPackageLI(newPackage, true); 16226 } 16227 // Add back the old system package 16228 try { 16229 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 16230 } catch (PackageManagerException e) { 16231 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 16232 } 16233 16234 synchronized (mPackages) { 16235 if (disabledSystem) { 16236 enableSystemPackageLPw(deletedPackage); 16237 } 16238 16239 // Ensure the installer package name up to date 16240 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 16241 16242 // Update permissions for restored package 16243 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 16244 16245 mSettings.writeLPr(); 16246 } 16247 16248 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 16249 + " after failed upgrade"); 16250 } 16251 } 16252 16253 /** 16254 * Checks whether the parent or any of the child packages have a change shared 16255 * user. For a package to be a valid update the shred users of the parent and 16256 * the children should match. We may later support changing child shared users. 16257 * @param oldPkg The updated package. 16258 * @param newPkg The update package. 16259 * @return The shared user that change between the versions. 16260 */ 16261 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 16262 PackageParser.Package newPkg) { 16263 // Check parent shared user 16264 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 16265 return newPkg.packageName; 16266 } 16267 // Check child shared users 16268 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 16269 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 16270 for (int i = 0; i < newChildCount; i++) { 16271 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 16272 // If this child was present, did it have the same shared user? 16273 for (int j = 0; j < oldChildCount; j++) { 16274 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 16275 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 16276 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 16277 return newChildPkg.packageName; 16278 } 16279 } 16280 } 16281 return null; 16282 } 16283 16284 private void removeNativeBinariesLI(PackageSetting ps) { 16285 // Remove the lib path for the parent package 16286 if (ps != null) { 16287 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 16288 // Remove the lib path for the child packages 16289 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 16290 for (int i = 0; i < childCount; i++) { 16291 PackageSetting childPs = null; 16292 synchronized (mPackages) { 16293 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 16294 } 16295 if (childPs != null) { 16296 NativeLibraryHelper.removeNativeBinariesLI(childPs 16297 .legacyNativeLibraryPathString); 16298 } 16299 } 16300 } 16301 } 16302 16303 private void enableSystemPackageLPw(PackageParser.Package pkg) { 16304 // Enable the parent package 16305 mSettings.enableSystemPackageLPw(pkg.packageName); 16306 // Enable the child packages 16307 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16308 for (int i = 0; i < childCount; i++) { 16309 PackageParser.Package childPkg = pkg.childPackages.get(i); 16310 mSettings.enableSystemPackageLPw(childPkg.packageName); 16311 } 16312 } 16313 16314 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 16315 PackageParser.Package newPkg) { 16316 // Disable the parent package (parent always replaced) 16317 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 16318 // Disable the child packages 16319 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 16320 for (int i = 0; i < childCount; i++) { 16321 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 16322 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 16323 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 16324 } 16325 return disabled; 16326 } 16327 16328 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 16329 String installerPackageName) { 16330 // Enable the parent package 16331 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 16332 // Enable the child packages 16333 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16334 for (int i = 0; i < childCount; i++) { 16335 PackageParser.Package childPkg = pkg.childPackages.get(i); 16336 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 16337 } 16338 } 16339 16340 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 16341 // Collect all used permissions in the UID 16342 ArraySet<String> usedPermissions = new ArraySet<>(); 16343 final int packageCount = su.packages.size(); 16344 for (int i = 0; i < packageCount; i++) { 16345 PackageSetting ps = su.packages.valueAt(i); 16346 if (ps.pkg == null) { 16347 continue; 16348 } 16349 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 16350 for (int j = 0; j < requestedPermCount; j++) { 16351 String permission = ps.pkg.requestedPermissions.get(j); 16352 BasePermission bp = mSettings.mPermissions.get(permission); 16353 if (bp != null) { 16354 usedPermissions.add(permission); 16355 } 16356 } 16357 } 16358 16359 PermissionsState permissionsState = su.getPermissionsState(); 16360 // Prune install permissions 16361 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 16362 final int installPermCount = installPermStates.size(); 16363 for (int i = installPermCount - 1; i >= 0; i--) { 16364 PermissionState permissionState = installPermStates.get(i); 16365 if (!usedPermissions.contains(permissionState.getName())) { 16366 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 16367 if (bp != null) { 16368 permissionsState.revokeInstallPermission(bp); 16369 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 16370 PackageManager.MASK_PERMISSION_FLAGS, 0); 16371 } 16372 } 16373 } 16374 16375 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 16376 16377 // Prune runtime permissions 16378 for (int userId : allUserIds) { 16379 List<PermissionState> runtimePermStates = permissionsState 16380 .getRuntimePermissionStates(userId); 16381 final int runtimePermCount = runtimePermStates.size(); 16382 for (int i = runtimePermCount - 1; i >= 0; i--) { 16383 PermissionState permissionState = runtimePermStates.get(i); 16384 if (!usedPermissions.contains(permissionState.getName())) { 16385 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 16386 if (bp != null) { 16387 permissionsState.revokeRuntimePermission(bp, userId); 16388 permissionsState.updatePermissionFlags(bp, userId, 16389 PackageManager.MASK_PERMISSION_FLAGS, 0); 16390 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 16391 runtimePermissionChangedUserIds, userId); 16392 } 16393 } 16394 } 16395 } 16396 16397 return runtimePermissionChangedUserIds; 16398 } 16399 16400 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 16401 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) { 16402 // Update the parent package setting 16403 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 16404 res, user, installReason); 16405 // Update the child packages setting 16406 final int childCount = (newPackage.childPackages != null) 16407 ? newPackage.childPackages.size() : 0; 16408 for (int i = 0; i < childCount; i++) { 16409 PackageParser.Package childPackage = newPackage.childPackages.get(i); 16410 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 16411 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 16412 childRes.origUsers, childRes, user, installReason); 16413 } 16414 } 16415 16416 private void updateSettingsInternalLI(PackageParser.Package newPackage, 16417 String installerPackageName, int[] allUsers, int[] installedForUsers, 16418 PackageInstalledInfo res, UserHandle user, int installReason) { 16419 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 16420 16421 String pkgName = newPackage.packageName; 16422 synchronized (mPackages) { 16423 //write settings. the installStatus will be incomplete at this stage. 16424 //note that the new package setting would have already been 16425 //added to mPackages. It hasn't been persisted yet. 16426 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 16427 // TODO: Remove this write? It's also written at the end of this method 16428 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 16429 mSettings.writeLPr(); 16430 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16431 } 16432 16433 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 16434 synchronized (mPackages) { 16435 updatePermissionsLPw(newPackage.packageName, newPackage, 16436 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 16437 ? UPDATE_PERMISSIONS_ALL : 0)); 16438 // For system-bundled packages, we assume that installing an upgraded version 16439 // of the package implies that the user actually wants to run that new code, 16440 // so we enable the package. 16441 PackageSetting ps = mSettings.mPackages.get(pkgName); 16442 final int userId = user.getIdentifier(); 16443 if (ps != null) { 16444 if (isSystemApp(newPackage)) { 16445 if (DEBUG_INSTALL) { 16446 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 16447 } 16448 // Enable system package for requested users 16449 if (res.origUsers != null) { 16450 for (int origUserId : res.origUsers) { 16451 if (userId == UserHandle.USER_ALL || userId == origUserId) { 16452 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 16453 origUserId, installerPackageName); 16454 } 16455 } 16456 } 16457 // Also convey the prior install/uninstall state 16458 if (allUsers != null && installedForUsers != null) { 16459 for (int currentUserId : allUsers) { 16460 final boolean installed = ArrayUtils.contains( 16461 installedForUsers, currentUserId); 16462 if (DEBUG_INSTALL) { 16463 Slog.d(TAG, " user " + currentUserId + " => " + installed); 16464 } 16465 ps.setInstalled(installed, currentUserId); 16466 } 16467 // these install state changes will be persisted in the 16468 // upcoming call to mSettings.writeLPr(). 16469 } 16470 } 16471 // It's implied that when a user requests installation, they want the app to be 16472 // installed and enabled. 16473 if (userId != UserHandle.USER_ALL) { 16474 ps.setInstalled(true, userId); 16475 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 16476 } 16477 16478 // When replacing an existing package, preserve the original install reason for all 16479 // users that had the package installed before. 16480 final Set<Integer> previousUserIds = new ArraySet<>(); 16481 if (res.removedInfo != null && res.removedInfo.installReasons != null) { 16482 final int installReasonCount = res.removedInfo.installReasons.size(); 16483 for (int i = 0; i < installReasonCount; i++) { 16484 final int previousUserId = res.removedInfo.installReasons.keyAt(i); 16485 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i); 16486 ps.setInstallReason(previousInstallReason, previousUserId); 16487 previousUserIds.add(previousUserId); 16488 } 16489 } 16490 16491 // Set install reason for users that are having the package newly installed. 16492 if (userId == UserHandle.USER_ALL) { 16493 for (int currentUserId : sUserManager.getUserIds()) { 16494 if (!previousUserIds.contains(currentUserId)) { 16495 ps.setInstallReason(installReason, currentUserId); 16496 } 16497 } 16498 } else if (!previousUserIds.contains(userId)) { 16499 ps.setInstallReason(installReason, userId); 16500 } 16501 mSettings.writeKernelMappingLPr(ps); 16502 } 16503 res.name = pkgName; 16504 res.uid = newPackage.applicationInfo.uid; 16505 res.pkg = newPackage; 16506 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 16507 mSettings.setInstallerPackageName(pkgName, installerPackageName); 16508 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16509 //to update install status 16510 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 16511 mSettings.writeLPr(); 16512 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16513 } 16514 16515 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16516 } 16517 16518 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 16519 try { 16520 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 16521 installPackageLI(args, res); 16522 } finally { 16523 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16524 } 16525 } 16526 16527 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 16528 final int installFlags = args.installFlags; 16529 final String installerPackageName = args.installerPackageName; 16530 final String volumeUuid = args.volumeUuid; 16531 final File tmpPackageFile = new File(args.getCodePath()); 16532 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 16533 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 16534 || (args.volumeUuid != null)); 16535 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); 16536 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); 16537 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 16538 boolean replace = false; 16539 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 16540 if (args.move != null) { 16541 // moving a complete application; perform an initial scan on the new install location 16542 scanFlags |= SCAN_INITIAL; 16543 } 16544 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 16545 scanFlags |= SCAN_DONT_KILL_APP; 16546 } 16547 if (instantApp) { 16548 scanFlags |= SCAN_AS_INSTANT_APP; 16549 } 16550 if (fullApp) { 16551 scanFlags |= SCAN_AS_FULL_APP; 16552 } 16553 16554 // Result object to be returned 16555 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16556 16557 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 16558 16559 // Sanity check 16560 if (instantApp && (forwardLocked || onExternal)) { 16561 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 16562 + " external=" + onExternal); 16563 res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); 16564 return; 16565 } 16566 16567 // Retrieve PackageSettings and parse package 16568 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 16569 | PackageParser.PARSE_ENFORCE_CODE 16570 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 16571 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 16572 | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0) 16573 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 16574 PackageParser pp = new PackageParser(); 16575 pp.setSeparateProcesses(mSeparateProcesses); 16576 pp.setDisplayMetrics(mMetrics); 16577 pp.setCallback(mPackageParserCallback); 16578 16579 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 16580 final PackageParser.Package pkg; 16581 try { 16582 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 16583 } catch (PackageParserException e) { 16584 res.setError("Failed parse during installPackageLI", e); 16585 return; 16586 } finally { 16587 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16588 } 16589 16590 // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2 16591 if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) { 16592 Slog.w(TAG, "Instant app package " + pkg.packageName 16593 + " does not target O, this will be a fatal error."); 16594 // STOPSHIP: Make this a fatal error 16595 pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O; 16596 } 16597 if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) { 16598 Slog.w(TAG, "Instant app package " + pkg.packageName 16599 + " does not target targetSandboxVersion 2, this will be a fatal error."); 16600 // STOPSHIP: Make this a fatal error 16601 pkg.applicationInfo.targetSandboxVersion = 2; 16602 } 16603 16604 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16605 // Static shared libraries have synthetic package names 16606 renameStaticSharedLibraryPackage(pkg); 16607 16608 // No static shared libs on external storage 16609 if (onExternal) { 16610 Slog.i(TAG, "Static shared libs can only be installed on internal storage."); 16611 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 16612 "Packages declaring static-shared libs cannot be updated"); 16613 return; 16614 } 16615 } 16616 16617 // If we are installing a clustered package add results for the children 16618 if (pkg.childPackages != null) { 16619 synchronized (mPackages) { 16620 final int childCount = pkg.childPackages.size(); 16621 for (int i = 0; i < childCount; i++) { 16622 PackageParser.Package childPkg = pkg.childPackages.get(i); 16623 PackageInstalledInfo childRes = new PackageInstalledInfo(); 16624 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 16625 childRes.pkg = childPkg; 16626 childRes.name = childPkg.packageName; 16627 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 16628 if (childPs != null) { 16629 childRes.origUsers = childPs.queryInstalledUsers( 16630 sUserManager.getUserIds(), true); 16631 } 16632 if ((mPackages.containsKey(childPkg.packageName))) { 16633 childRes.removedInfo = new PackageRemovedInfo(); 16634 childRes.removedInfo.removedPackage = childPkg.packageName; 16635 } 16636 if (res.addedChildPackages == null) { 16637 res.addedChildPackages = new ArrayMap<>(); 16638 } 16639 res.addedChildPackages.put(childPkg.packageName, childRes); 16640 } 16641 } 16642 } 16643 16644 // If package doesn't declare API override, mark that we have an install 16645 // time CPU ABI override. 16646 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 16647 pkg.cpuAbiOverride = args.abiOverride; 16648 } 16649 16650 String pkgName = res.name = pkg.packageName; 16651 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 16652 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 16653 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 16654 return; 16655 } 16656 } 16657 16658 try { 16659 // either use what we've been given or parse directly from the APK 16660 if (args.certificates != null) { 16661 try { 16662 PackageParser.populateCertificates(pkg, args.certificates); 16663 } catch (PackageParserException e) { 16664 // there was something wrong with the certificates we were given; 16665 // try to pull them from the APK 16666 PackageParser.collectCertificates(pkg, parseFlags); 16667 } 16668 } else { 16669 PackageParser.collectCertificates(pkg, parseFlags); 16670 } 16671 } catch (PackageParserException e) { 16672 res.setError("Failed collect during installPackageLI", e); 16673 return; 16674 } 16675 16676 // Get rid of all references to package scan path via parser. 16677 pp = null; 16678 String oldCodePath = null; 16679 boolean systemApp = false; 16680 synchronized (mPackages) { 16681 // Check if installing already existing package 16682 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 16683 String oldName = mSettings.getRenamedPackageLPr(pkgName); 16684 if (pkg.mOriginalPackages != null 16685 && pkg.mOriginalPackages.contains(oldName) 16686 && mPackages.containsKey(oldName)) { 16687 // This package is derived from an original package, 16688 // and this device has been updating from that original 16689 // name. We must continue using the original name, so 16690 // rename the new package here. 16691 pkg.setPackageName(oldName); 16692 pkgName = pkg.packageName; 16693 replace = true; 16694 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 16695 + oldName + " pkgName=" + pkgName); 16696 } else if (mPackages.containsKey(pkgName)) { 16697 // This package, under its official name, already exists 16698 // on the device; we should replace it. 16699 replace = true; 16700 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 16701 } 16702 16703 // Child packages are installed through the parent package 16704 if (pkg.parentPackage != null) { 16705 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 16706 "Package " + pkg.packageName + " is child of package " 16707 + pkg.parentPackage.parentPackage + ". Child packages " 16708 + "can be updated only through the parent package."); 16709 return; 16710 } 16711 16712 if (replace) { 16713 // Prevent apps opting out from runtime permissions 16714 PackageParser.Package oldPackage = mPackages.get(pkgName); 16715 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 16716 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 16717 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 16718 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 16719 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 16720 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 16721 + " doesn't support runtime permissions but the old" 16722 + " target SDK " + oldTargetSdk + " does."); 16723 return; 16724 } 16725 // Prevent apps from downgrading their targetSandbox. 16726 final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion; 16727 final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion; 16728 if (oldTargetSandbox == 2 && newTargetSandbox != 2) { 16729 res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE, 16730 "Package " + pkg.packageName + " new target sandbox " 16731 + newTargetSandbox + " is incompatible with the previous value of" 16732 + oldTargetSandbox + "."); 16733 return; 16734 } 16735 16736 // Prevent installing of child packages 16737 if (oldPackage.parentPackage != null) { 16738 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 16739 "Package " + pkg.packageName + " is child of package " 16740 + oldPackage.parentPackage + ". Child packages " 16741 + "can be updated only through the parent package."); 16742 return; 16743 } 16744 } 16745 } 16746 16747 PackageSetting ps = mSettings.mPackages.get(pkgName); 16748 if (ps != null) { 16749 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 16750 16751 // Static shared libs have same package with different versions where 16752 // we internally use a synthetic package name to allow multiple versions 16753 // of the same package, therefore we need to compare signatures against 16754 // the package setting for the latest library version. 16755 PackageSetting signatureCheckPs = ps; 16756 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16757 SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg); 16758 if (libraryEntry != null) { 16759 signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk); 16760 } 16761 } 16762 16763 // Quick sanity check that we're signed correctly if updating; 16764 // we'll check this again later when scanning, but we want to 16765 // bail early here before tripping over redefined permissions. 16766 if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) { 16767 if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) { 16768 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 16769 + pkg.packageName + " upgrade keys do not match the " 16770 + "previously installed version"); 16771 return; 16772 } 16773 } else { 16774 try { 16775 verifySignaturesLP(signatureCheckPs, pkg); 16776 } catch (PackageManagerException e) { 16777 res.setError(e.error, e.getMessage()); 16778 return; 16779 } 16780 } 16781 16782 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 16783 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 16784 systemApp = (ps.pkg.applicationInfo.flags & 16785 ApplicationInfo.FLAG_SYSTEM) != 0; 16786 } 16787 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 16788 } 16789 16790 int N = pkg.permissions.size(); 16791 for (int i = N-1; i >= 0; i--) { 16792 PackageParser.Permission perm = pkg.permissions.get(i); 16793 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 16794 16795 // Don't allow anyone but the platform to define ephemeral permissions. 16796 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0 16797 && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { 16798 Slog.w(TAG, "Package " + pkg.packageName 16799 + " attempting to delcare ephemeral permission " 16800 + perm.info.name + "; Removing ephemeral."); 16801 perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL; 16802 } 16803 // Check whether the newly-scanned package wants to define an already-defined perm 16804 if (bp != null) { 16805 // If the defining package is signed with our cert, it's okay. This 16806 // also includes the "updating the same package" case, of course. 16807 // "updating same package" could also involve key-rotation. 16808 final boolean sigsOk; 16809 if (bp.sourcePackage.equals(pkg.packageName) 16810 && (bp.packageSetting instanceof PackageSetting) 16811 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 16812 scanFlags))) { 16813 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 16814 } else { 16815 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 16816 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 16817 } 16818 if (!sigsOk) { 16819 // If the owning package is the system itself, we log but allow 16820 // install to proceed; we fail the install on all other permission 16821 // redefinitions. 16822 if (!bp.sourcePackage.equals("android")) { 16823 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 16824 + pkg.packageName + " attempting to redeclare permission " 16825 + perm.info.name + " already owned by " + bp.sourcePackage); 16826 res.origPermission = perm.info.name; 16827 res.origPackage = bp.sourcePackage; 16828 return; 16829 } else { 16830 Slog.w(TAG, "Package " + pkg.packageName 16831 + " attempting to redeclare system permission " 16832 + perm.info.name + "; ignoring new declaration"); 16833 pkg.permissions.remove(i); 16834 } 16835 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { 16836 // Prevent apps to change protection level to dangerous from any other 16837 // type as this would allow a privilege escalation where an app adds a 16838 // normal/signature permission in other app's group and later redefines 16839 // it as dangerous leading to the group auto-grant. 16840 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) 16841 == PermissionInfo.PROTECTION_DANGEROUS) { 16842 if (bp != null && !bp.isRuntime()) { 16843 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a " 16844 + "non-runtime permission " + perm.info.name 16845 + " to runtime; keeping old protection level"); 16846 perm.info.protectionLevel = bp.protectionLevel; 16847 } 16848 } 16849 } 16850 } 16851 } 16852 } 16853 16854 if (systemApp) { 16855 if (onExternal) { 16856 // Abort update; system app can't be replaced with app on sdcard 16857 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 16858 "Cannot install updates to system apps on sdcard"); 16859 return; 16860 } else if (instantApp) { 16861 // Abort update; system app can't be replaced with an instant app 16862 res.setError(INSTALL_FAILED_INSTANT_APP_INVALID, 16863 "Cannot update a system app with an instant app"); 16864 return; 16865 } 16866 } 16867 16868 if (args.move != null) { 16869 // We did an in-place move, so dex is ready to roll 16870 scanFlags |= SCAN_NO_DEX; 16871 scanFlags |= SCAN_MOVE; 16872 16873 synchronized (mPackages) { 16874 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16875 if (ps == null) { 16876 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 16877 "Missing settings for moved package " + pkgName); 16878 } 16879 16880 // We moved the entire application as-is, so bring over the 16881 // previously derived ABI information. 16882 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 16883 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 16884 } 16885 16886 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 16887 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 16888 scanFlags |= SCAN_NO_DEX; 16889 16890 try { 16891 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 16892 args.abiOverride : pkg.cpuAbiOverride); 16893 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 16894 true /*extractLibs*/, mAppLib32InstallDir); 16895 } catch (PackageManagerException pme) { 16896 Slog.e(TAG, "Error deriving application ABI", pme); 16897 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 16898 return; 16899 } 16900 16901 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 16902 // Do not run PackageDexOptimizer through the local performDexOpt 16903 // method because `pkg` may not be in `mPackages` yet. 16904 // 16905 // Also, don't fail application installs if the dexopt step fails. 16906 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 16907 null /* instructionSets */, false /* checkProfiles */, 16908 getCompilerFilterForReason(REASON_INSTALL), 16909 getOrCreateCompilerPackageStats(pkg), 16910 mDexManager.isUsedByOtherApps(pkg.packageName)); 16911 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 16912 16913 // Notify BackgroundDexOptService that the package has been changed. 16914 // If this is an update of a package which used to fail to compile, 16915 // BDOS will remove it from its blacklist. 16916 // TODO: Layering violation 16917 BackgroundDexOptService.notifyPackageChanged(pkg.packageName); 16918 } 16919 16920 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 16921 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 16922 return; 16923 } 16924 16925 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 16926 16927 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 16928 "installPackageLI")) { 16929 if (replace) { 16930 if (pkg.applicationInfo.isStaticSharedLibrary()) { 16931 // Static libs have a synthetic package name containing the version 16932 // and cannot be updated as an update would get a new package name, 16933 // unless this is the exact same version code which is useful for 16934 // development. 16935 PackageParser.Package existingPkg = mPackages.get(pkg.packageName); 16936 if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) { 16937 res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring " 16938 + "static-shared libs cannot be updated"); 16939 return; 16940 } 16941 } 16942 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 16943 installerPackageName, res, args.installReason); 16944 } else { 16945 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 16946 args.user, installerPackageName, volumeUuid, res, args.installReason); 16947 } 16948 } 16949 synchronized (mPackages) { 16950 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16951 if (ps != null) { 16952 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 16953 ps.setUpdateAvailable(false /*updateAvailable*/); 16954 } 16955 16956 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16957 for (int i = 0; i < childCount; i++) { 16958 PackageParser.Package childPkg = pkg.childPackages.get(i); 16959 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 16960 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 16961 if (childPs != null) { 16962 childRes.newUsers = childPs.queryInstalledUsers( 16963 sUserManager.getUserIds(), true); 16964 } 16965 } 16966 16967 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 16968 updateSequenceNumberLP(pkgName, res.newUsers); 16969 updateInstantAppInstallerLocked(); 16970 } 16971 } 16972 } 16973 16974 private void startIntentFilterVerifications(int userId, boolean replacing, 16975 PackageParser.Package pkg) { 16976 if (mIntentFilterVerifierComponent == null) { 16977 Slog.w(TAG, "No IntentFilter verification will not be done as " 16978 + "there is no IntentFilterVerifier available!"); 16979 return; 16980 } 16981 16982 final int verifierUid = getPackageUid( 16983 mIntentFilterVerifierComponent.getPackageName(), 16984 MATCH_DEBUG_TRIAGED_MISSING, 16985 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 16986 16987 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 16988 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 16989 mHandler.sendMessage(msg); 16990 16991 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 16992 for (int i = 0; i < childCount; i++) { 16993 PackageParser.Package childPkg = pkg.childPackages.get(i); 16994 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 16995 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 16996 mHandler.sendMessage(msg); 16997 } 16998 } 16999 17000 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 17001 PackageParser.Package pkg) { 17002 int size = pkg.activities.size(); 17003 if (size == 0) { 17004 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 17005 "No activity, so no need to verify any IntentFilter!"); 17006 return; 17007 } 17008 17009 final boolean hasDomainURLs = hasDomainURLs(pkg); 17010 if (!hasDomainURLs) { 17011 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 17012 "No domain URLs, so no need to verify any IntentFilter!"); 17013 return; 17014 } 17015 17016 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 17017 + " if any IntentFilter from the " + size 17018 + " Activities needs verification ..."); 17019 17020 int count = 0; 17021 final String packageName = pkg.packageName; 17022 17023 synchronized (mPackages) { 17024 // If this is a new install and we see that we've already run verification for this 17025 // package, we have nothing to do: it means the state was restored from backup. 17026 if (!replacing) { 17027 IntentFilterVerificationInfo ivi = 17028 mSettings.getIntentFilterVerificationLPr(packageName); 17029 if (ivi != null) { 17030 if (DEBUG_DOMAIN_VERIFICATION) { 17031 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 17032 + ivi.getStatusString()); 17033 } 17034 return; 17035 } 17036 } 17037 17038 // If any filters need to be verified, then all need to be. 17039 boolean needToVerify = false; 17040 for (PackageParser.Activity a : pkg.activities) { 17041 for (ActivityIntentInfo filter : a.intents) { 17042 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 17043 if (DEBUG_DOMAIN_VERIFICATION) { 17044 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 17045 } 17046 needToVerify = true; 17047 break; 17048 } 17049 } 17050 } 17051 17052 if (needToVerify) { 17053 final int verificationId = mIntentFilterVerificationToken++; 17054 for (PackageParser.Activity a : pkg.activities) { 17055 for (ActivityIntentInfo filter : a.intents) { 17056 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 17057 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 17058 "Verification needed for IntentFilter:" + filter.toString()); 17059 mIntentFilterVerifier.addOneIntentFilterVerification( 17060 verifierUid, userId, verificationId, filter, packageName); 17061 count++; 17062 } 17063 } 17064 } 17065 } 17066 } 17067 17068 if (count > 0) { 17069 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 17070 + " IntentFilter verification" + (count > 1 ? "s" : "") 17071 + " for userId:" + userId); 17072 mIntentFilterVerifier.startVerifications(userId); 17073 } else { 17074 if (DEBUG_DOMAIN_VERIFICATION) { 17075 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 17076 } 17077 } 17078 } 17079 17080 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 17081 final ComponentName cn = filter.activity.getComponentName(); 17082 final String packageName = cn.getPackageName(); 17083 17084 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 17085 packageName); 17086 if (ivi == null) { 17087 return true; 17088 } 17089 int status = ivi.getStatus(); 17090 switch (status) { 17091 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 17092 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 17093 return true; 17094 17095 default: 17096 // Nothing to do 17097 return false; 17098 } 17099 } 17100 17101 private static boolean isMultiArch(ApplicationInfo info) { 17102 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 17103 } 17104 17105 private static boolean isExternal(PackageParser.Package pkg) { 17106 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 17107 } 17108 17109 private static boolean isExternal(PackageSetting ps) { 17110 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 17111 } 17112 17113 private static boolean isSystemApp(PackageParser.Package pkg) { 17114 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 17115 } 17116 17117 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 17118 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 17119 } 17120 17121 private static boolean hasDomainURLs(PackageParser.Package pkg) { 17122 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 17123 } 17124 17125 private static boolean isSystemApp(PackageSetting ps) { 17126 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 17127 } 17128 17129 private static boolean isUpdatedSystemApp(PackageSetting ps) { 17130 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 17131 } 17132 17133 private int packageFlagsToInstallFlags(PackageSetting ps) { 17134 int installFlags = 0; 17135 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 17136 // This existing package was an external ASEC install when we have 17137 // the external flag without a UUID 17138 installFlags |= PackageManager.INSTALL_EXTERNAL; 17139 } 17140 if (ps.isForwardLocked()) { 17141 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 17142 } 17143 return installFlags; 17144 } 17145 17146 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 17147 if (isExternal(pkg)) { 17148 if (TextUtils.isEmpty(pkg.volumeUuid)) { 17149 return StorageManager.UUID_PRIMARY_PHYSICAL; 17150 } else { 17151 return pkg.volumeUuid; 17152 } 17153 } else { 17154 return StorageManager.UUID_PRIVATE_INTERNAL; 17155 } 17156 } 17157 17158 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 17159 if (isExternal(pkg)) { 17160 if (TextUtils.isEmpty(pkg.volumeUuid)) { 17161 return mSettings.getExternalVersion(); 17162 } else { 17163 return mSettings.findOrCreateVersion(pkg.volumeUuid); 17164 } 17165 } else { 17166 return mSettings.getInternalVersion(); 17167 } 17168 } 17169 17170 private void deleteTempPackageFiles() { 17171 final FilenameFilter filter = new FilenameFilter() { 17172 public boolean accept(File dir, String name) { 17173 return name.startsWith("vmdl") && name.endsWith(".tmp"); 17174 } 17175 }; 17176 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 17177 file.delete(); 17178 } 17179 } 17180 17181 @Override 17182 public void deletePackageAsUser(String packageName, int versionCode, 17183 IPackageDeleteObserver observer, int userId, int flags) { 17184 deletePackageVersioned(new VersionedPackage(packageName, versionCode), 17185 new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags); 17186 } 17187 17188 @Override 17189 public void deletePackageVersioned(VersionedPackage versionedPackage, 17190 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 17191 mContext.enforceCallingOrSelfPermission( 17192 android.Manifest.permission.DELETE_PACKAGES, null); 17193 Preconditions.checkNotNull(versionedPackage); 17194 Preconditions.checkNotNull(observer); 17195 Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(), 17196 PackageManager.VERSION_CODE_HIGHEST, 17197 Integer.MAX_VALUE, "versionCode must be >= -1"); 17198 17199 final String packageName = versionedPackage.getPackageName(); 17200 // TODO: We will change version code to long, so in the new API it is long 17201 final int versionCode = (int) versionedPackage.getVersionCode(); 17202 final String internalPackageName; 17203 synchronized (mPackages) { 17204 // Normalize package name to handle renamed packages and static libs 17205 internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(), 17206 // TODO: We will change version code to long, so in the new API it is long 17207 (int) versionedPackage.getVersionCode()); 17208 } 17209 17210 final int uid = Binder.getCallingUid(); 17211 if (!isOrphaned(internalPackageName) 17212 && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) { 17213 try { 17214 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 17215 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 17216 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 17217 observer.onUserActionRequired(intent); 17218 } catch (RemoteException re) { 17219 } 17220 return; 17221 } 17222 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 17223 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 17224 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 17225 mContext.enforceCallingOrSelfPermission( 17226 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 17227 "deletePackage for user " + userId); 17228 } 17229 17230 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 17231 try { 17232 observer.onPackageDeleted(packageName, 17233 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 17234 } catch (RemoteException re) { 17235 } 17236 return; 17237 } 17238 17239 if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) { 17240 try { 17241 observer.onPackageDeleted(packageName, 17242 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 17243 } catch (RemoteException re) { 17244 } 17245 return; 17246 } 17247 17248 if (DEBUG_REMOVE) { 17249 Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId 17250 + " deleteAllUsers: " + deleteAllUsers + " version=" 17251 + (versionCode == PackageManager.VERSION_CODE_HIGHEST 17252 ? "VERSION_CODE_HIGHEST" : versionCode)); 17253 } 17254 // Queue up an async operation since the package deletion may take a little while. 17255 mHandler.post(new Runnable() { 17256 public void run() { 17257 mHandler.removeCallbacks(this); 17258 int returnCode; 17259 if (!deleteAllUsers) { 17260 returnCode = deletePackageX(internalPackageName, versionCode, 17261 userId, deleteFlags); 17262 } else { 17263 int[] blockUninstallUserIds = getBlockUninstallForUsers( 17264 internalPackageName, users); 17265 // If nobody is blocking uninstall, proceed with delete for all users 17266 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 17267 returnCode = deletePackageX(internalPackageName, versionCode, 17268 userId, deleteFlags); 17269 } else { 17270 // Otherwise uninstall individually for users with blockUninstalls=false 17271 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 17272 for (int userId : users) { 17273 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 17274 returnCode = deletePackageX(internalPackageName, versionCode, 17275 userId, userFlags); 17276 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 17277 Slog.w(TAG, "Package delete failed for user " + userId 17278 + ", returnCode " + returnCode); 17279 } 17280 } 17281 } 17282 // The app has only been marked uninstalled for certain users. 17283 // We still need to report that delete was blocked 17284 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 17285 } 17286 } 17287 try { 17288 observer.onPackageDeleted(packageName, returnCode, null); 17289 } catch (RemoteException e) { 17290 Log.i(TAG, "Observer no longer exists."); 17291 } //end catch 17292 } //end run 17293 }); 17294 } 17295 17296 private String resolveExternalPackageNameLPr(PackageParser.Package pkg) { 17297 if (pkg.staticSharedLibName != null) { 17298 return pkg.manifestPackageName; 17299 } 17300 return pkg.packageName; 17301 } 17302 17303 private String resolveInternalPackageNameLPr(String packageName, int versionCode) { 17304 // Handle renamed packages 17305 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName); 17306 packageName = normalizedPackageName != null ? normalizedPackageName : packageName; 17307 17308 // Is this a static library? 17309 SparseArray<SharedLibraryEntry> versionedLib = 17310 mStaticLibsByDeclaringPackage.get(packageName); 17311 if (versionedLib == null || versionedLib.size() <= 0) { 17312 return packageName; 17313 } 17314 17315 // Figure out which lib versions the caller can see 17316 SparseIntArray versionsCallerCanSee = null; 17317 final int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); 17318 if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID 17319 && callingAppId != Process.ROOT_UID) { 17320 versionsCallerCanSee = new SparseIntArray(); 17321 String libName = versionedLib.valueAt(0).info.getName(); 17322 String[] uidPackages = getPackagesForUid(Binder.getCallingUid()); 17323 if (uidPackages != null) { 17324 for (String uidPackage : uidPackages) { 17325 PackageSetting ps = mSettings.getPackageLPr(uidPackage); 17326 final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName); 17327 if (libIdx >= 0) { 17328 final int libVersion = ps.usesStaticLibrariesVersions[libIdx]; 17329 versionsCallerCanSee.append(libVersion, libVersion); 17330 } 17331 } 17332 } 17333 } 17334 17335 // Caller can see nothing - done 17336 if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) { 17337 return packageName; 17338 } 17339 17340 // Find the version the caller can see and the app version code 17341 SharedLibraryEntry highestVersion = null; 17342 final int versionCount = versionedLib.size(); 17343 for (int i = 0; i < versionCount; i++) { 17344 SharedLibraryEntry libEntry = versionedLib.valueAt(i); 17345 if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey( 17346 libEntry.info.getVersion()) < 0) { 17347 continue; 17348 } 17349 // TODO: We will change version code to long, so in the new API it is long 17350 final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode(); 17351 if (versionCode != PackageManager.VERSION_CODE_HIGHEST) { 17352 if (libVersionCode == versionCode) { 17353 return libEntry.apk; 17354 } 17355 } else if (highestVersion == null) { 17356 highestVersion = libEntry; 17357 } else if (libVersionCode > highestVersion.info 17358 .getDeclaringPackage().getVersionCode()) { 17359 highestVersion = libEntry; 17360 } 17361 } 17362 17363 if (highestVersion != null) { 17364 return highestVersion.apk; 17365 } 17366 17367 return packageName; 17368 } 17369 17370 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) { 17371 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID 17372 || callingUid == Process.SYSTEM_UID) { 17373 return true; 17374 } 17375 final int callingUserId = UserHandle.getUserId(callingUid); 17376 // If the caller installed the pkgName, then allow it to silently uninstall. 17377 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) { 17378 return true; 17379 } 17380 17381 // Allow package verifier to silently uninstall. 17382 if (mRequiredVerifierPackage != null && 17383 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) { 17384 return true; 17385 } 17386 17387 // Allow package uninstaller to silently uninstall. 17388 if (mRequiredUninstallerPackage != null && 17389 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { 17390 return true; 17391 } 17392 17393 // Allow storage manager to silently uninstall. 17394 if (mStorageManagerPackage != null && 17395 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { 17396 return true; 17397 } 17398 return false; 17399 } 17400 17401 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 17402 int[] result = EMPTY_INT_ARRAY; 17403 for (int userId : userIds) { 17404 if (getBlockUninstallForUser(packageName, userId)) { 17405 result = ArrayUtils.appendInt(result, userId); 17406 } 17407 } 17408 return result; 17409 } 17410 17411 @Override 17412 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 17413 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 17414 } 17415 17416 private boolean isPackageDeviceAdmin(String packageName, int userId) { 17417 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 17418 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 17419 try { 17420 if (dpm != null) { 17421 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 17422 /* callingUserOnly =*/ false); 17423 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 17424 : deviceOwnerComponentName.getPackageName(); 17425 // Does the package contains the device owner? 17426 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 17427 // this check is probably not needed, since DO should be registered as a device 17428 // admin on some user too. (Original bug for this: b/17657954) 17429 if (packageName.equals(deviceOwnerPackageName)) { 17430 return true; 17431 } 17432 // Does it contain a device admin for any user? 17433 int[] users; 17434 if (userId == UserHandle.USER_ALL) { 17435 users = sUserManager.getUserIds(); 17436 } else { 17437 users = new int[]{userId}; 17438 } 17439 for (int i = 0; i < users.length; ++i) { 17440 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 17441 return true; 17442 } 17443 } 17444 } 17445 } catch (RemoteException e) { 17446 } 17447 return false; 17448 } 17449 17450 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 17451 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 17452 } 17453 17454 /** 17455 * This method is an internal method that could be get invoked either 17456 * to delete an installed package or to clean up a failed installation. 17457 * After deleting an installed package, a broadcast is sent to notify any 17458 * listeners that the package has been removed. For cleaning up a failed 17459 * installation, the broadcast is not necessary since the package's 17460 * installation wouldn't have sent the initial broadcast either 17461 * The key steps in deleting a package are 17462 * deleting the package information in internal structures like mPackages, 17463 * deleting the packages base directories through installd 17464 * updating mSettings to reflect current status 17465 * persisting settings for later use 17466 * sending a broadcast if necessary 17467 */ 17468 private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) { 17469 final PackageRemovedInfo info = new PackageRemovedInfo(); 17470 final boolean res; 17471 17472 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 17473 ? UserHandle.USER_ALL : userId; 17474 17475 if (isPackageDeviceAdmin(packageName, removeUser)) { 17476 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 17477 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 17478 } 17479 17480 PackageSetting uninstalledPs = null; 17481 PackageParser.Package pkg = null; 17482 17483 // for the uninstall-updates case and restricted profiles, remember the per- 17484 // user handle installed state 17485 int[] allUsers; 17486 synchronized (mPackages) { 17487 uninstalledPs = mSettings.mPackages.get(packageName); 17488 if (uninstalledPs == null) { 17489 Slog.w(TAG, "Not removing non-existent package " + packageName); 17490 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17491 } 17492 17493 if (versionCode != PackageManager.VERSION_CODE_HIGHEST 17494 && uninstalledPs.versionCode != versionCode) { 17495 Slog.w(TAG, "Not removing package " + packageName + " with versionCode " 17496 + uninstalledPs.versionCode + " != " + versionCode); 17497 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17498 } 17499 17500 // Static shared libs can be declared by any package, so let us not 17501 // allow removing a package if it provides a lib others depend on. 17502 pkg = mPackages.get(packageName); 17503 if (pkg != null && pkg.staticSharedLibName != null) { 17504 SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName, 17505 pkg.staticSharedLibVersion); 17506 if (libEntry != null) { 17507 List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr( 17508 libEntry.info, 0, userId); 17509 if (!ArrayUtils.isEmpty(libClientPackages)) { 17510 Slog.w(TAG, "Not removing package " + pkg.manifestPackageName 17511 + " hosting lib " + libEntry.info.getName() + " version " 17512 + libEntry.info.getVersion() + " used by " + libClientPackages); 17513 return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY; 17514 } 17515 } 17516 } 17517 17518 allUsers = sUserManager.getUserIds(); 17519 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 17520 } 17521 17522 final int freezeUser; 17523 if (isUpdatedSystemApp(uninstalledPs) 17524 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 17525 // We're downgrading a system app, which will apply to all users, so 17526 // freeze them all during the downgrade 17527 freezeUser = UserHandle.USER_ALL; 17528 } else { 17529 freezeUser = removeUser; 17530 } 17531 17532 synchronized (mInstallLock) { 17533 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 17534 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 17535 deleteFlags, "deletePackageX")) { 17536 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 17537 deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null); 17538 } 17539 synchronized (mPackages) { 17540 if (res) { 17541 if (pkg != null) { 17542 mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers); 17543 } 17544 updateSequenceNumberLP(packageName, info.removedUsers); 17545 updateInstantAppInstallerLocked(); 17546 } 17547 } 17548 } 17549 17550 if (res) { 17551 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 17552 info.sendPackageRemovedBroadcasts(killApp); 17553 info.sendSystemPackageUpdatedBroadcasts(); 17554 info.sendSystemPackageAppearedBroadcasts(); 17555 } 17556 // Force a gc here. 17557 Runtime.getRuntime().gc(); 17558 // Delete the resources here after sending the broadcast to let 17559 // other processes clean up before deleting resources. 17560 if (info.args != null) { 17561 synchronized (mInstallLock) { 17562 info.args.doPostDeleteLI(true); 17563 } 17564 } 17565 17566 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 17567 } 17568 17569 class PackageRemovedInfo { 17570 String removedPackage; 17571 int uid = -1; 17572 int removedAppId = -1; 17573 int[] origUsers; 17574 int[] removedUsers = null; 17575 SparseArray<Integer> installReasons; 17576 boolean isRemovedPackageSystemUpdate = false; 17577 boolean isUpdate; 17578 boolean dataRemoved; 17579 boolean removedForAllUsers; 17580 boolean isStaticSharedLib; 17581 // Clean up resources deleted packages. 17582 InstallArgs args = null; 17583 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 17584 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 17585 17586 void sendPackageRemovedBroadcasts(boolean killApp) { 17587 sendPackageRemovedBroadcastInternal(killApp); 17588 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 17589 for (int i = 0; i < childCount; i++) { 17590 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 17591 childInfo.sendPackageRemovedBroadcastInternal(killApp); 17592 } 17593 } 17594 17595 void sendSystemPackageUpdatedBroadcasts() { 17596 if (isRemovedPackageSystemUpdate) { 17597 sendSystemPackageUpdatedBroadcastsInternal(); 17598 final int childCount = (removedChildPackages != null) 17599 ? removedChildPackages.size() : 0; 17600 for (int i = 0; i < childCount; i++) { 17601 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 17602 if (childInfo.isRemovedPackageSystemUpdate) { 17603 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 17604 } 17605 } 17606 } 17607 } 17608 17609 void sendSystemPackageAppearedBroadcasts() { 17610 final int packageCount = (appearedChildPackages != null) 17611 ? appearedChildPackages.size() : 0; 17612 for (int i = 0; i < packageCount; i++) { 17613 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 17614 sendPackageAddedForNewUsers(installedInfo.name, true, 17615 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers); 17616 } 17617 } 17618 17619 private void sendSystemPackageUpdatedBroadcastsInternal() { 17620 Bundle extras = new Bundle(2); 17621 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 17622 extras.putBoolean(Intent.EXTRA_REPLACING, true); 17623 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 17624 extras, 0, null, null, null); 17625 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 17626 extras, 0, null, null, null); 17627 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 17628 null, 0, removedPackage, null, null); 17629 } 17630 17631 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 17632 // Don't send static shared library removal broadcasts as these 17633 // libs are visible only the the apps that depend on them an one 17634 // cannot remove the library if it has a dependency. 17635 if (isStaticSharedLib) { 17636 return; 17637 } 17638 Bundle extras = new Bundle(2); 17639 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 17640 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 17641 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 17642 if (isUpdate || isRemovedPackageSystemUpdate) { 17643 extras.putBoolean(Intent.EXTRA_REPLACING, true); 17644 } 17645 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 17646 if (removedPackage != null) { 17647 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 17648 extras, 0, null, null, removedUsers); 17649 if (dataRemoved && !isRemovedPackageSystemUpdate) { 17650 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 17651 removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, 17652 null, null, removedUsers); 17653 } 17654 } 17655 if (removedAppId >= 0) { 17656 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 17657 removedUsers); 17658 } 17659 } 17660 } 17661 17662 /* 17663 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 17664 * flag is not set, the data directory is removed as well. 17665 * make sure this flag is set for partially installed apps. If not its meaningless to 17666 * delete a partially installed application. 17667 */ 17668 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 17669 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 17670 String packageName = ps.name; 17671 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 17672 // Retrieve object to delete permissions for shared user later on 17673 final PackageParser.Package deletedPkg; 17674 final PackageSetting deletedPs; 17675 // reader 17676 synchronized (mPackages) { 17677 deletedPkg = mPackages.get(packageName); 17678 deletedPs = mSettings.mPackages.get(packageName); 17679 if (outInfo != null) { 17680 outInfo.removedPackage = packageName; 17681 outInfo.isStaticSharedLib = deletedPkg != null 17682 && deletedPkg.staticSharedLibName != null; 17683 outInfo.removedUsers = deletedPs != null 17684 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 17685 : null; 17686 } 17687 } 17688 17689 removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0); 17690 17691 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 17692 final PackageParser.Package resolvedPkg; 17693 if (deletedPkg != null) { 17694 resolvedPkg = deletedPkg; 17695 } else { 17696 // We don't have a parsed package when it lives on an ejected 17697 // adopted storage device, so fake something together 17698 resolvedPkg = new PackageParser.Package(ps.name); 17699 resolvedPkg.setVolumeUuid(ps.volumeUuid); 17700 } 17701 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 17702 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 17703 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 17704 if (outInfo != null) { 17705 outInfo.dataRemoved = true; 17706 } 17707 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 17708 } 17709 17710 int removedAppId = -1; 17711 17712 // writer 17713 synchronized (mPackages) { 17714 boolean installedStateChanged = false; 17715 if (deletedPs != null) { 17716 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 17717 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 17718 clearDefaultBrowserIfNeeded(packageName); 17719 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 17720 removedAppId = mSettings.removePackageLPw(packageName); 17721 if (outInfo != null) { 17722 outInfo.removedAppId = removedAppId; 17723 } 17724 updatePermissionsLPw(deletedPs.name, null, 0); 17725 if (deletedPs.sharedUser != null) { 17726 // Remove permissions associated with package. Since runtime 17727 // permissions are per user we have to kill the removed package 17728 // or packages running under the shared user of the removed 17729 // package if revoking the permissions requested only by the removed 17730 // package is successful and this causes a change in gids. 17731 for (int userId : UserManagerService.getInstance().getUserIds()) { 17732 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 17733 userId); 17734 if (userIdToKill == UserHandle.USER_ALL 17735 || userIdToKill >= UserHandle.USER_SYSTEM) { 17736 // If gids changed for this user, kill all affected packages. 17737 mHandler.post(new Runnable() { 17738 @Override 17739 public void run() { 17740 // This has to happen with no lock held. 17741 killApplication(deletedPs.name, deletedPs.appId, 17742 KILL_APP_REASON_GIDS_CHANGED); 17743 } 17744 }); 17745 break; 17746 } 17747 } 17748 } 17749 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 17750 } 17751 // make sure to preserve per-user disabled state if this removal was just 17752 // a downgrade of a system app to the factory package 17753 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 17754 if (DEBUG_REMOVE) { 17755 Slog.d(TAG, "Propagating install state across downgrade"); 17756 } 17757 for (int userId : allUserHandles) { 17758 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 17759 if (DEBUG_REMOVE) { 17760 Slog.d(TAG, " user " + userId + " => " + installed); 17761 } 17762 if (installed != ps.getInstalled(userId)) { 17763 installedStateChanged = true; 17764 } 17765 ps.setInstalled(installed, userId); 17766 } 17767 } 17768 } 17769 // can downgrade to reader 17770 if (writeSettings) { 17771 // Save settings now 17772 mSettings.writeLPr(); 17773 } 17774 if (installedStateChanged) { 17775 mSettings.writeKernelMappingLPr(ps); 17776 } 17777 } 17778 if (removedAppId != -1) { 17779 // A user ID was deleted here. Go through all users and remove it 17780 // from KeyStore. 17781 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId); 17782 } 17783 } 17784 17785 static boolean locationIsPrivileged(File path) { 17786 try { 17787 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 17788 .getCanonicalPath(); 17789 return path.getCanonicalPath().startsWith(privilegedAppDir); 17790 } catch (IOException e) { 17791 Slog.e(TAG, "Unable to access code path " + path); 17792 } 17793 return false; 17794 } 17795 17796 /* 17797 * Tries to delete system package. 17798 */ 17799 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 17800 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 17801 boolean writeSettings) { 17802 if (deletedPs.parentPackageName != null) { 17803 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 17804 return false; 17805 } 17806 17807 final boolean applyUserRestrictions 17808 = (allUserHandles != null) && (outInfo.origUsers != null); 17809 final PackageSetting disabledPs; 17810 // Confirm if the system package has been updated 17811 // An updated system app can be deleted. This will also have to restore 17812 // the system pkg from system partition 17813 // reader 17814 synchronized (mPackages) { 17815 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 17816 } 17817 17818 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 17819 + " disabledPs=" + disabledPs); 17820 17821 if (disabledPs == null) { 17822 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 17823 return false; 17824 } else if (DEBUG_REMOVE) { 17825 Slog.d(TAG, "Deleting system pkg from data partition"); 17826 } 17827 17828 if (DEBUG_REMOVE) { 17829 if (applyUserRestrictions) { 17830 Slog.d(TAG, "Remembering install states:"); 17831 for (int userId : allUserHandles) { 17832 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 17833 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 17834 } 17835 } 17836 } 17837 17838 // Delete the updated package 17839 outInfo.isRemovedPackageSystemUpdate = true; 17840 if (outInfo.removedChildPackages != null) { 17841 final int childCount = (deletedPs.childPackageNames != null) 17842 ? deletedPs.childPackageNames.size() : 0; 17843 for (int i = 0; i < childCount; i++) { 17844 String childPackageName = deletedPs.childPackageNames.get(i); 17845 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 17846 .contains(childPackageName)) { 17847 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 17848 childPackageName); 17849 if (childInfo != null) { 17850 childInfo.isRemovedPackageSystemUpdate = true; 17851 } 17852 } 17853 } 17854 } 17855 17856 if (disabledPs.versionCode < deletedPs.versionCode) { 17857 // Delete data for downgrades 17858 flags &= ~PackageManager.DELETE_KEEP_DATA; 17859 } else { 17860 // Preserve data by setting flag 17861 flags |= PackageManager.DELETE_KEEP_DATA; 17862 } 17863 17864 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 17865 outInfo, writeSettings, disabledPs.pkg); 17866 if (!ret) { 17867 return false; 17868 } 17869 17870 // writer 17871 synchronized (mPackages) { 17872 // Reinstate the old system package 17873 enableSystemPackageLPw(disabledPs.pkg); 17874 // Remove any native libraries from the upgraded package. 17875 removeNativeBinariesLI(deletedPs); 17876 } 17877 17878 // Install the system package 17879 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 17880 int parseFlags = mDefParseFlags 17881 | PackageParser.PARSE_MUST_BE_APK 17882 | PackageParser.PARSE_IS_SYSTEM 17883 | PackageParser.PARSE_IS_SYSTEM_DIR; 17884 if (locationIsPrivileged(disabledPs.codePath)) { 17885 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 17886 } 17887 17888 final PackageParser.Package newPkg; 17889 try { 17890 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */, 17891 0 /* currentTime */, null); 17892 } catch (PackageManagerException e) { 17893 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 17894 + e.getMessage()); 17895 return false; 17896 } 17897 17898 try { 17899 // update shared libraries for the newly re-installed system package 17900 updateSharedLibrariesLPr(newPkg, null); 17901 } catch (PackageManagerException e) { 17902 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 17903 } 17904 17905 prepareAppDataAfterInstallLIF(newPkg); 17906 17907 // writer 17908 synchronized (mPackages) { 17909 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 17910 17911 // Propagate the permissions state as we do not want to drop on the floor 17912 // runtime permissions. The update permissions method below will take 17913 // care of removing obsolete permissions and grant install permissions. 17914 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 17915 updatePermissionsLPw(newPkg.packageName, newPkg, 17916 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 17917 17918 if (applyUserRestrictions) { 17919 boolean installedStateChanged = false; 17920 if (DEBUG_REMOVE) { 17921 Slog.d(TAG, "Propagating install state across reinstall"); 17922 } 17923 for (int userId : allUserHandles) { 17924 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 17925 if (DEBUG_REMOVE) { 17926 Slog.d(TAG, " user " + userId + " => " + installed); 17927 } 17928 if (installed != ps.getInstalled(userId)) { 17929 installedStateChanged = true; 17930 } 17931 ps.setInstalled(installed, userId); 17932 17933 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17934 } 17935 // Regardless of writeSettings we need to ensure that this restriction 17936 // state propagation is persisted 17937 mSettings.writeAllUsersPackageRestrictionsLPr(); 17938 if (installedStateChanged) { 17939 mSettings.writeKernelMappingLPr(ps); 17940 } 17941 } 17942 // can downgrade to reader here 17943 if (writeSettings) { 17944 mSettings.writeLPr(); 17945 } 17946 } 17947 return true; 17948 } 17949 17950 private boolean deleteInstalledPackageLIF(PackageSetting ps, 17951 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 17952 PackageRemovedInfo outInfo, boolean writeSettings, 17953 PackageParser.Package replacingPackage) { 17954 synchronized (mPackages) { 17955 if (outInfo != null) { 17956 outInfo.uid = ps.appId; 17957 } 17958 17959 if (outInfo != null && outInfo.removedChildPackages != null) { 17960 final int childCount = (ps.childPackageNames != null) 17961 ? ps.childPackageNames.size() : 0; 17962 for (int i = 0; i < childCount; i++) { 17963 String childPackageName = ps.childPackageNames.get(i); 17964 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 17965 if (childPs == null) { 17966 return false; 17967 } 17968 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 17969 childPackageName); 17970 if (childInfo != null) { 17971 childInfo.uid = childPs.appId; 17972 } 17973 } 17974 } 17975 } 17976 17977 // Delete package data from internal structures and also remove data if flag is set 17978 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 17979 17980 // Delete the child packages data 17981 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 17982 for (int i = 0; i < childCount; i++) { 17983 PackageSetting childPs; 17984 synchronized (mPackages) { 17985 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 17986 } 17987 if (childPs != null) { 17988 PackageRemovedInfo childOutInfo = (outInfo != null 17989 && outInfo.removedChildPackages != null) 17990 ? outInfo.removedChildPackages.get(childPs.name) : null; 17991 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 17992 && (replacingPackage != null 17993 && !replacingPackage.hasChildPackage(childPs.name)) 17994 ? flags & ~DELETE_KEEP_DATA : flags; 17995 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 17996 deleteFlags, writeSettings); 17997 } 17998 } 17999 18000 // Delete application code and resources only for parent packages 18001 if (ps.parentPackageName == null) { 18002 if (deleteCodeAndResources && (outInfo != null)) { 18003 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 18004 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 18005 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 18006 } 18007 } 18008 18009 return true; 18010 } 18011 18012 @Override 18013 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 18014 int userId) { 18015 mContext.enforceCallingOrSelfPermission( 18016 android.Manifest.permission.DELETE_PACKAGES, null); 18017 synchronized (mPackages) { 18018 PackageSetting ps = mSettings.mPackages.get(packageName); 18019 if (ps == null) { 18020 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 18021 return false; 18022 } 18023 // Cannot block uninstall of static shared libs as they are 18024 // considered a part of the using app (emulating static linking). 18025 // Also static libs are installed always on internal storage. 18026 PackageParser.Package pkg = mPackages.get(packageName); 18027 if (pkg != null && pkg.staticSharedLibName != null) { 18028 Slog.w(TAG, "Cannot block uninstall of package: " + packageName 18029 + " providing static shared library: " + pkg.staticSharedLibName); 18030 return false; 18031 } 18032 if (!ps.getInstalled(userId)) { 18033 // Can't block uninstall for an app that is not installed or enabled. 18034 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 18035 return false; 18036 } 18037 ps.setBlockUninstall(blockUninstall, userId); 18038 mSettings.writePackageRestrictionsLPr(userId); 18039 } 18040 return true; 18041 } 18042 18043 @Override 18044 public boolean getBlockUninstallForUser(String packageName, int userId) { 18045 synchronized (mPackages) { 18046 PackageSetting ps = mSettings.mPackages.get(packageName); 18047 if (ps == null) { 18048 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 18049 return false; 18050 } 18051 return ps.getBlockUninstall(userId); 18052 } 18053 } 18054 18055 @Override 18056 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 18057 int callingUid = Binder.getCallingUid(); 18058 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 18059 throw new SecurityException( 18060 "setRequiredForSystemUser can only be run by the system or root"); 18061 } 18062 synchronized (mPackages) { 18063 PackageSetting ps = mSettings.mPackages.get(packageName); 18064 if (ps == null) { 18065 Log.w(TAG, "Package doesn't exist: " + packageName); 18066 return false; 18067 } 18068 if (systemUserApp) { 18069 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 18070 } else { 18071 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 18072 } 18073 mSettings.writeLPr(); 18074 } 18075 return true; 18076 } 18077 18078 /* 18079 * This method handles package deletion in general 18080 */ 18081 private boolean deletePackageLIF(String packageName, UserHandle user, 18082 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 18083 PackageRemovedInfo outInfo, boolean writeSettings, 18084 PackageParser.Package replacingPackage) { 18085 if (packageName == null) { 18086 Slog.w(TAG, "Attempt to delete null packageName."); 18087 return false; 18088 } 18089 18090 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 18091 18092 PackageSetting ps; 18093 synchronized (mPackages) { 18094 ps = mSettings.mPackages.get(packageName); 18095 if (ps == null) { 18096 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 18097 return false; 18098 } 18099 18100 if (ps.parentPackageName != null && (!isSystemApp(ps) 18101 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 18102 if (DEBUG_REMOVE) { 18103 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 18104 + ((user == null) ? UserHandle.USER_ALL : user)); 18105 } 18106 final int removedUserId = (user != null) ? user.getIdentifier() 18107 : UserHandle.USER_ALL; 18108 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 18109 return false; 18110 } 18111 markPackageUninstalledForUserLPw(ps, user); 18112 scheduleWritePackageRestrictionsLocked(user); 18113 return true; 18114 } 18115 } 18116 18117 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 18118 && user.getIdentifier() != UserHandle.USER_ALL)) { 18119 // The caller is asking that the package only be deleted for a single 18120 // user. To do this, we just mark its uninstalled state and delete 18121 // its data. If this is a system app, we only allow this to happen if 18122 // they have set the special DELETE_SYSTEM_APP which requests different 18123 // semantics than normal for uninstalling system apps. 18124 markPackageUninstalledForUserLPw(ps, user); 18125 18126 if (!isSystemApp(ps)) { 18127 // Do not uninstall the APK if an app should be cached 18128 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 18129 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 18130 // Other user still have this package installed, so all 18131 // we need to do is clear this user's data and save that 18132 // it is uninstalled. 18133 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 18134 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 18135 return false; 18136 } 18137 scheduleWritePackageRestrictionsLocked(user); 18138 return true; 18139 } else { 18140 // We need to set it back to 'installed' so the uninstall 18141 // broadcasts will be sent correctly. 18142 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 18143 ps.setInstalled(true, user.getIdentifier()); 18144 mSettings.writeKernelMappingLPr(ps); 18145 } 18146 } else { 18147 // This is a system app, so we assume that the 18148 // other users still have this package installed, so all 18149 // we need to do is clear this user's data and save that 18150 // it is uninstalled. 18151 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 18152 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 18153 return false; 18154 } 18155 scheduleWritePackageRestrictionsLocked(user); 18156 return true; 18157 } 18158 } 18159 18160 // If we are deleting a composite package for all users, keep track 18161 // of result for each child. 18162 if (ps.childPackageNames != null && outInfo != null) { 18163 synchronized (mPackages) { 18164 final int childCount = ps.childPackageNames.size(); 18165 outInfo.removedChildPackages = new ArrayMap<>(childCount); 18166 for (int i = 0; i < childCount; i++) { 18167 String childPackageName = ps.childPackageNames.get(i); 18168 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 18169 childInfo.removedPackage = childPackageName; 18170 outInfo.removedChildPackages.put(childPackageName, childInfo); 18171 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 18172 if (childPs != null) { 18173 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 18174 } 18175 } 18176 } 18177 } 18178 18179 boolean ret = false; 18180 if (isSystemApp(ps)) { 18181 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 18182 // When an updated system application is deleted we delete the existing resources 18183 // as well and fall back to existing code in system partition 18184 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 18185 } else { 18186 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 18187 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 18188 outInfo, writeSettings, replacingPackage); 18189 } 18190 18191 // Take a note whether we deleted the package for all users 18192 if (outInfo != null) { 18193 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 18194 if (outInfo.removedChildPackages != null) { 18195 synchronized (mPackages) { 18196 final int childCount = outInfo.removedChildPackages.size(); 18197 for (int i = 0; i < childCount; i++) { 18198 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 18199 if (childInfo != null) { 18200 childInfo.removedForAllUsers = mPackages.get( 18201 childInfo.removedPackage) == null; 18202 } 18203 } 18204 } 18205 } 18206 // If we uninstalled an update to a system app there may be some 18207 // child packages that appeared as they are declared in the system 18208 // app but were not declared in the update. 18209 if (isSystemApp(ps)) { 18210 synchronized (mPackages) { 18211 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name); 18212 final int childCount = (updatedPs.childPackageNames != null) 18213 ? updatedPs.childPackageNames.size() : 0; 18214 for (int i = 0; i < childCount; i++) { 18215 String childPackageName = updatedPs.childPackageNames.get(i); 18216 if (outInfo.removedChildPackages == null 18217 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 18218 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 18219 if (childPs == null) { 18220 continue; 18221 } 18222 PackageInstalledInfo installRes = new PackageInstalledInfo(); 18223 installRes.name = childPackageName; 18224 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 18225 installRes.pkg = mPackages.get(childPackageName); 18226 installRes.uid = childPs.pkg.applicationInfo.uid; 18227 if (outInfo.appearedChildPackages == null) { 18228 outInfo.appearedChildPackages = new ArrayMap<>(); 18229 } 18230 outInfo.appearedChildPackages.put(childPackageName, installRes); 18231 } 18232 } 18233 } 18234 } 18235 } 18236 18237 return ret; 18238 } 18239 18240 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 18241 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 18242 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 18243 for (int nextUserId : userIds) { 18244 if (DEBUG_REMOVE) { 18245 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 18246 } 18247 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 18248 false /*installed*/, 18249 true /*stopped*/, 18250 true /*notLaunched*/, 18251 false /*hidden*/, 18252 false /*suspended*/, 18253 false /*instantApp*/, 18254 null /*lastDisableAppCaller*/, 18255 null /*enabledComponents*/, 18256 null /*disabledComponents*/, 18257 false /*blockUninstall*/, 18258 ps.readUserState(nextUserId).domainVerificationStatus, 18259 0, PackageManager.INSTALL_REASON_UNKNOWN); 18260 } 18261 mSettings.writeKernelMappingLPr(ps); 18262 } 18263 18264 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 18265 PackageRemovedInfo outInfo) { 18266 final PackageParser.Package pkg; 18267 synchronized (mPackages) { 18268 pkg = mPackages.get(ps.name); 18269 } 18270 18271 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 18272 : new int[] {userId}; 18273 for (int nextUserId : userIds) { 18274 if (DEBUG_REMOVE) { 18275 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 18276 + nextUserId); 18277 } 18278 18279 destroyAppDataLIF(pkg, userId, 18280 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 18281 destroyAppProfilesLIF(pkg, userId); 18282 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 18283 schedulePackageCleaning(ps.name, nextUserId, false); 18284 synchronized (mPackages) { 18285 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 18286 scheduleWritePackageRestrictionsLocked(nextUserId); 18287 } 18288 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 18289 } 18290 } 18291 18292 if (outInfo != null) { 18293 outInfo.removedPackage = ps.name; 18294 outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null; 18295 outInfo.removedAppId = ps.appId; 18296 outInfo.removedUsers = userIds; 18297 } 18298 18299 return true; 18300 } 18301 18302 private final class ClearStorageConnection implements ServiceConnection { 18303 IMediaContainerService mContainerService; 18304 18305 @Override 18306 public void onServiceConnected(ComponentName name, IBinder service) { 18307 synchronized (this) { 18308 mContainerService = IMediaContainerService.Stub 18309 .asInterface(Binder.allowBlocking(service)); 18310 notifyAll(); 18311 } 18312 } 18313 18314 @Override 18315 public void onServiceDisconnected(ComponentName name) { 18316 } 18317 } 18318 18319 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 18320 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 18321 18322 final boolean mounted; 18323 if (Environment.isExternalStorageEmulated()) { 18324 mounted = true; 18325 } else { 18326 final String status = Environment.getExternalStorageState(); 18327 18328 mounted = status.equals(Environment.MEDIA_MOUNTED) 18329 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 18330 } 18331 18332 if (!mounted) { 18333 return; 18334 } 18335 18336 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 18337 int[] users; 18338 if (userId == UserHandle.USER_ALL) { 18339 users = sUserManager.getUserIds(); 18340 } else { 18341 users = new int[] { userId }; 18342 } 18343 final ClearStorageConnection conn = new ClearStorageConnection(); 18344 if (mContext.bindServiceAsUser( 18345 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 18346 try { 18347 for (int curUser : users) { 18348 long timeout = SystemClock.uptimeMillis() + 5000; 18349 synchronized (conn) { 18350 long now; 18351 while (conn.mContainerService == null && 18352 (now = SystemClock.uptimeMillis()) < timeout) { 18353 try { 18354 conn.wait(timeout - now); 18355 } catch (InterruptedException e) { 18356 } 18357 } 18358 } 18359 if (conn.mContainerService == null) { 18360 return; 18361 } 18362 18363 final UserEnvironment userEnv = new UserEnvironment(curUser); 18364 clearDirectory(conn.mContainerService, 18365 userEnv.buildExternalStorageAppCacheDirs(packageName)); 18366 if (allData) { 18367 clearDirectory(conn.mContainerService, 18368 userEnv.buildExternalStorageAppDataDirs(packageName)); 18369 clearDirectory(conn.mContainerService, 18370 userEnv.buildExternalStorageAppMediaDirs(packageName)); 18371 } 18372 } 18373 } finally { 18374 mContext.unbindService(conn); 18375 } 18376 } 18377 } 18378 18379 @Override 18380 public void clearApplicationProfileData(String packageName) { 18381 enforceSystemOrRoot("Only the system can clear all profile data"); 18382 18383 final PackageParser.Package pkg; 18384 synchronized (mPackages) { 18385 pkg = mPackages.get(packageName); 18386 } 18387 18388 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 18389 synchronized (mInstallLock) { 18390 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 18391 } 18392 } 18393 } 18394 18395 @Override 18396 public void clearApplicationUserData(final String packageName, 18397 final IPackageDataObserver observer, final int userId) { 18398 mContext.enforceCallingOrSelfPermission( 18399 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 18400 18401 enforceCrossUserPermission(Binder.getCallingUid(), userId, 18402 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 18403 18404 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 18405 throw new SecurityException("Cannot clear data for a protected package: " 18406 + packageName); 18407 } 18408 // Queue up an async operation since the package deletion may take a little while. 18409 mHandler.post(new Runnable() { 18410 public void run() { 18411 mHandler.removeCallbacks(this); 18412 final boolean succeeded; 18413 try (PackageFreezer freezer = freezePackage(packageName, 18414 "clearApplicationUserData")) { 18415 synchronized (mInstallLock) { 18416 succeeded = clearApplicationUserDataLIF(packageName, userId); 18417 } 18418 clearExternalStorageDataSync(packageName, userId, true); 18419 synchronized (mPackages) { 18420 mInstantAppRegistry.deleteInstantApplicationMetadataLPw( 18421 packageName, userId); 18422 } 18423 } 18424 if (succeeded) { 18425 // invoke DeviceStorageMonitor's update method to clear any notifications 18426 DeviceStorageMonitorInternal dsm = LocalServices 18427 .getService(DeviceStorageMonitorInternal.class); 18428 if (dsm != null) { 18429 dsm.checkMemory(); 18430 } 18431 } 18432 if(observer != null) { 18433 try { 18434 observer.onRemoveCompleted(packageName, succeeded); 18435 } catch (RemoteException e) { 18436 Log.i(TAG, "Observer no longer exists."); 18437 } 18438 } //end if observer 18439 } //end run 18440 }); 18441 } 18442 18443 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 18444 if (packageName == null) { 18445 Slog.w(TAG, "Attempt to delete null packageName."); 18446 return false; 18447 } 18448 18449 // Try finding details about the requested package 18450 PackageParser.Package pkg; 18451 synchronized (mPackages) { 18452 pkg = mPackages.get(packageName); 18453 if (pkg == null) { 18454 final PackageSetting ps = mSettings.mPackages.get(packageName); 18455 if (ps != null) { 18456 pkg = ps.pkg; 18457 } 18458 } 18459 18460 if (pkg == null) { 18461 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 18462 return false; 18463 } 18464 18465 PackageSetting ps = (PackageSetting) pkg.mExtras; 18466 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 18467 } 18468 18469 clearAppDataLIF(pkg, userId, 18470 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 18471 18472 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18473 removeKeystoreDataIfNeeded(userId, appId); 18474 18475 UserManagerInternal umInternal = getUserManagerInternal(); 18476 final int flags; 18477 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 18478 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18479 } else if (umInternal.isUserRunning(userId)) { 18480 flags = StorageManager.FLAG_STORAGE_DE; 18481 } else { 18482 flags = 0; 18483 } 18484 prepareAppDataContentsLIF(pkg, userId, flags); 18485 18486 return true; 18487 } 18488 18489 /** 18490 * Reverts user permission state changes (permissions and flags) in 18491 * all packages for a given user. 18492 * 18493 * @param userId The device user for which to do a reset. 18494 */ 18495 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 18496 final int packageCount = mPackages.size(); 18497 for (int i = 0; i < packageCount; i++) { 18498 PackageParser.Package pkg = mPackages.valueAt(i); 18499 PackageSetting ps = (PackageSetting) pkg.mExtras; 18500 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 18501 } 18502 } 18503 18504 private void resetNetworkPolicies(int userId) { 18505 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 18506 } 18507 18508 /** 18509 * Reverts user permission state changes (permissions and flags). 18510 * 18511 * @param ps The package for which to reset. 18512 * @param userId The device user for which to do a reset. 18513 */ 18514 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 18515 final PackageSetting ps, final int userId) { 18516 if (ps.pkg == null) { 18517 return; 18518 } 18519 18520 // These are flags that can change base on user actions. 18521 final int userSettableMask = FLAG_PERMISSION_USER_SET 18522 | FLAG_PERMISSION_USER_FIXED 18523 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 18524 | FLAG_PERMISSION_REVIEW_REQUIRED; 18525 18526 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 18527 | FLAG_PERMISSION_POLICY_FIXED; 18528 18529 boolean writeInstallPermissions = false; 18530 boolean writeRuntimePermissions = false; 18531 18532 final int permissionCount = ps.pkg.requestedPermissions.size(); 18533 for (int i = 0; i < permissionCount; i++) { 18534 String permission = ps.pkg.requestedPermissions.get(i); 18535 18536 BasePermission bp = mSettings.mPermissions.get(permission); 18537 if (bp == null) { 18538 continue; 18539 } 18540 18541 // If shared user we just reset the state to which only this app contributed. 18542 if (ps.sharedUser != null) { 18543 boolean used = false; 18544 final int packageCount = ps.sharedUser.packages.size(); 18545 for (int j = 0; j < packageCount; j++) { 18546 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 18547 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 18548 && pkg.pkg.requestedPermissions.contains(permission)) { 18549 used = true; 18550 break; 18551 } 18552 } 18553 if (used) { 18554 continue; 18555 } 18556 } 18557 18558 PermissionsState permissionsState = ps.getPermissionsState(); 18559 18560 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 18561 18562 // Always clear the user settable flags. 18563 final boolean hasInstallState = permissionsState.getInstallPermissionState( 18564 bp.name) != null; 18565 // If permission review is enabled and this is a legacy app, mark the 18566 // permission as requiring a review as this is the initial state. 18567 int flags = 0; 18568 if (mPermissionReviewRequired 18569 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 18570 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 18571 } 18572 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 18573 if (hasInstallState) { 18574 writeInstallPermissions = true; 18575 } else { 18576 writeRuntimePermissions = true; 18577 } 18578 } 18579 18580 // Below is only runtime permission handling. 18581 if (!bp.isRuntime()) { 18582 continue; 18583 } 18584 18585 // Never clobber system or policy. 18586 if ((oldFlags & policyOrSystemFlags) != 0) { 18587 continue; 18588 } 18589 18590 // If this permission was granted by default, make sure it is. 18591 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 18592 if (permissionsState.grantRuntimePermission(bp, userId) 18593 != PERMISSION_OPERATION_FAILURE) { 18594 writeRuntimePermissions = true; 18595 } 18596 // If permission review is enabled the permissions for a legacy apps 18597 // are represented as constantly granted runtime ones, so don't revoke. 18598 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 18599 // Otherwise, reset the permission. 18600 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 18601 switch (revokeResult) { 18602 case PERMISSION_OPERATION_SUCCESS: 18603 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 18604 writeRuntimePermissions = true; 18605 final int appId = ps.appId; 18606 mHandler.post(new Runnable() { 18607 @Override 18608 public void run() { 18609 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 18610 } 18611 }); 18612 } break; 18613 } 18614 } 18615 } 18616 18617 // Synchronously write as we are taking permissions away. 18618 if (writeRuntimePermissions) { 18619 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 18620 } 18621 18622 // Synchronously write as we are taking permissions away. 18623 if (writeInstallPermissions) { 18624 mSettings.writeLPr(); 18625 } 18626 } 18627 18628 /** 18629 * Remove entries from the keystore daemon. Will only remove it if the 18630 * {@code appId} is valid. 18631 */ 18632 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 18633 if (appId < 0) { 18634 return; 18635 } 18636 18637 final KeyStore keyStore = KeyStore.getInstance(); 18638 if (keyStore != null) { 18639 if (userId == UserHandle.USER_ALL) { 18640 for (final int individual : sUserManager.getUserIds()) { 18641 keyStore.clearUid(UserHandle.getUid(individual, appId)); 18642 } 18643 } else { 18644 keyStore.clearUid(UserHandle.getUid(userId, appId)); 18645 } 18646 } else { 18647 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 18648 } 18649 } 18650 18651 @Override 18652 public void deleteApplicationCacheFiles(final String packageName, 18653 final IPackageDataObserver observer) { 18654 final int userId = UserHandle.getCallingUserId(); 18655 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 18656 } 18657 18658 @Override 18659 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 18660 final IPackageDataObserver observer) { 18661 mContext.enforceCallingOrSelfPermission( 18662 android.Manifest.permission.DELETE_CACHE_FILES, null); 18663 enforceCrossUserPermission(Binder.getCallingUid(), userId, 18664 /* requireFullPermission= */ true, /* checkShell= */ false, 18665 "delete application cache files"); 18666 18667 final PackageParser.Package pkg; 18668 synchronized (mPackages) { 18669 pkg = mPackages.get(packageName); 18670 } 18671 18672 // Queue up an async operation since the package deletion may take a little while. 18673 mHandler.post(new Runnable() { 18674 public void run() { 18675 synchronized (mInstallLock) { 18676 final int flags = StorageManager.FLAG_STORAGE_DE 18677 | StorageManager.FLAG_STORAGE_CE; 18678 // We're only clearing cache files, so we don't care if the 18679 // app is unfrozen and still able to run 18680 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 18681 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 18682 } 18683 clearExternalStorageDataSync(packageName, userId, false); 18684 if (observer != null) { 18685 try { 18686 observer.onRemoveCompleted(packageName, true); 18687 } catch (RemoteException e) { 18688 Log.i(TAG, "Observer no longer exists."); 18689 } 18690 } 18691 } 18692 }); 18693 } 18694 18695 @Override 18696 public void getPackageSizeInfo(final String packageName, int userHandle, 18697 final IPackageStatsObserver observer) { 18698 throw new UnsupportedOperationException( 18699 "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!"); 18700 } 18701 18702 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 18703 final PackageSetting ps; 18704 synchronized (mPackages) { 18705 ps = mSettings.mPackages.get(packageName); 18706 if (ps == null) { 18707 Slog.w(TAG, "Failed to find settings for " + packageName); 18708 return false; 18709 } 18710 } 18711 18712 final String[] packageNames = { packageName }; 18713 final long[] ceDataInodes = { ps.getCeDataInode(userId) }; 18714 final String[] codePaths = { ps.codePathString }; 18715 18716 try { 18717 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0, 18718 ps.appId, ceDataInodes, codePaths, stats); 18719 18720 // For now, ignore code size of packages on system partition 18721 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 18722 stats.codeSize = 0; 18723 } 18724 18725 // External clients expect these to be tracked separately 18726 stats.dataSize -= stats.cacheSize; 18727 18728 } catch (InstallerException e) { 18729 Slog.w(TAG, String.valueOf(e)); 18730 return false; 18731 } 18732 18733 return true; 18734 } 18735 18736 private int getUidTargetSdkVersionLockedLPr(int uid) { 18737 Object obj = mSettings.getUserIdLPr(uid); 18738 if (obj instanceof SharedUserSetting) { 18739 final SharedUserSetting sus = (SharedUserSetting) obj; 18740 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 18741 final Iterator<PackageSetting> it = sus.packages.iterator(); 18742 while (it.hasNext()) { 18743 final PackageSetting ps = it.next(); 18744 if (ps.pkg != null) { 18745 int v = ps.pkg.applicationInfo.targetSdkVersion; 18746 if (v < vers) vers = v; 18747 } 18748 } 18749 return vers; 18750 } else if (obj instanceof PackageSetting) { 18751 final PackageSetting ps = (PackageSetting) obj; 18752 if (ps.pkg != null) { 18753 return ps.pkg.applicationInfo.targetSdkVersion; 18754 } 18755 } 18756 return Build.VERSION_CODES.CUR_DEVELOPMENT; 18757 } 18758 18759 @Override 18760 public void addPreferredActivity(IntentFilter filter, int match, 18761 ComponentName[] set, ComponentName activity, int userId) { 18762 addPreferredActivityInternal(filter, match, set, activity, true, userId, 18763 "Adding preferred"); 18764 } 18765 18766 private void addPreferredActivityInternal(IntentFilter filter, int match, 18767 ComponentName[] set, ComponentName activity, boolean always, int userId, 18768 String opname) { 18769 // writer 18770 int callingUid = Binder.getCallingUid(); 18771 enforceCrossUserPermission(callingUid, userId, 18772 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 18773 if (filter.countActions() == 0) { 18774 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 18775 return; 18776 } 18777 synchronized (mPackages) { 18778 if (mContext.checkCallingOrSelfPermission( 18779 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18780 != PackageManager.PERMISSION_GRANTED) { 18781 if (getUidTargetSdkVersionLockedLPr(callingUid) 18782 < Build.VERSION_CODES.FROYO) { 18783 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 18784 + callingUid); 18785 return; 18786 } 18787 mContext.enforceCallingOrSelfPermission( 18788 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18789 } 18790 18791 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 18792 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 18793 + userId + ":"); 18794 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18795 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 18796 scheduleWritePackageRestrictionsLocked(userId); 18797 postPreferredActivityChangedBroadcast(userId); 18798 } 18799 } 18800 18801 private void postPreferredActivityChangedBroadcast(int userId) { 18802 mHandler.post(() -> { 18803 final IActivityManager am = ActivityManager.getService(); 18804 if (am == null) { 18805 return; 18806 } 18807 18808 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 18809 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18810 try { 18811 am.broadcastIntent(null, intent, null, null, 18812 0, null, null, null, android.app.AppOpsManager.OP_NONE, 18813 null, false, false, userId); 18814 } catch (RemoteException e) { 18815 } 18816 }); 18817 } 18818 18819 @Override 18820 public void replacePreferredActivity(IntentFilter filter, int match, 18821 ComponentName[] set, ComponentName activity, int userId) { 18822 if (filter.countActions() != 1) { 18823 throw new IllegalArgumentException( 18824 "replacePreferredActivity expects filter to have only 1 action."); 18825 } 18826 if (filter.countDataAuthorities() != 0 18827 || filter.countDataPaths() != 0 18828 || filter.countDataSchemes() > 1 18829 || filter.countDataTypes() != 0) { 18830 throw new IllegalArgumentException( 18831 "replacePreferredActivity expects filter to have no data authorities, " + 18832 "paths, or types; and at most one scheme."); 18833 } 18834 18835 final int callingUid = Binder.getCallingUid(); 18836 enforceCrossUserPermission(callingUid, userId, 18837 true /* requireFullPermission */, false /* checkShell */, 18838 "replace preferred activity"); 18839 synchronized (mPackages) { 18840 if (mContext.checkCallingOrSelfPermission( 18841 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18842 != PackageManager.PERMISSION_GRANTED) { 18843 if (getUidTargetSdkVersionLockedLPr(callingUid) 18844 < Build.VERSION_CODES.FROYO) { 18845 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 18846 + Binder.getCallingUid()); 18847 return; 18848 } 18849 mContext.enforceCallingOrSelfPermission( 18850 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18851 } 18852 18853 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 18854 if (pir != null) { 18855 // Get all of the existing entries that exactly match this filter. 18856 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 18857 if (existing != null && existing.size() == 1) { 18858 PreferredActivity cur = existing.get(0); 18859 if (DEBUG_PREFERRED) { 18860 Slog.i(TAG, "Checking replace of preferred:"); 18861 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18862 if (!cur.mPref.mAlways) { 18863 Slog.i(TAG, " -- CUR; not mAlways!"); 18864 } else { 18865 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 18866 Slog.i(TAG, " -- CUR: mSet=" 18867 + Arrays.toString(cur.mPref.mSetComponents)); 18868 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 18869 Slog.i(TAG, " -- NEW: mMatch=" 18870 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 18871 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 18872 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 18873 } 18874 } 18875 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 18876 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 18877 && cur.mPref.sameSet(set)) { 18878 // Setting the preferred activity to what it happens to be already 18879 if (DEBUG_PREFERRED) { 18880 Slog.i(TAG, "Replacing with same preferred activity " 18881 + cur.mPref.mShortComponent + " for user " 18882 + userId + ":"); 18883 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18884 } 18885 return; 18886 } 18887 } 18888 18889 if (existing != null) { 18890 if (DEBUG_PREFERRED) { 18891 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 18892 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 18893 } 18894 for (int i = 0; i < existing.size(); i++) { 18895 PreferredActivity pa = existing.get(i); 18896 if (DEBUG_PREFERRED) { 18897 Slog.i(TAG, "Removing existing preferred activity " 18898 + pa.mPref.mComponent + ":"); 18899 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 18900 } 18901 pir.removeFilter(pa); 18902 } 18903 } 18904 } 18905 addPreferredActivityInternal(filter, match, set, activity, true, userId, 18906 "Replacing preferred"); 18907 } 18908 } 18909 18910 @Override 18911 public void clearPackagePreferredActivities(String packageName) { 18912 final int uid = Binder.getCallingUid(); 18913 // writer 18914 synchronized (mPackages) { 18915 PackageParser.Package pkg = mPackages.get(packageName); 18916 if (pkg == null || pkg.applicationInfo.uid != uid) { 18917 if (mContext.checkCallingOrSelfPermission( 18918 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 18919 != PackageManager.PERMISSION_GRANTED) { 18920 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 18921 < Build.VERSION_CODES.FROYO) { 18922 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 18923 + Binder.getCallingUid()); 18924 return; 18925 } 18926 mContext.enforceCallingOrSelfPermission( 18927 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 18928 } 18929 } 18930 18931 int user = UserHandle.getCallingUserId(); 18932 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 18933 scheduleWritePackageRestrictionsLocked(user); 18934 } 18935 } 18936 } 18937 18938 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18939 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 18940 ArrayList<PreferredActivity> removed = null; 18941 boolean changed = false; 18942 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18943 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 18944 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18945 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 18946 continue; 18947 } 18948 Iterator<PreferredActivity> it = pir.filterIterator(); 18949 while (it.hasNext()) { 18950 PreferredActivity pa = it.next(); 18951 // Mark entry for removal only if it matches the package name 18952 // and the entry is of type "always". 18953 if (packageName == null || 18954 (pa.mPref.mComponent.getPackageName().equals(packageName) 18955 && pa.mPref.mAlways)) { 18956 if (removed == null) { 18957 removed = new ArrayList<PreferredActivity>(); 18958 } 18959 removed.add(pa); 18960 } 18961 } 18962 if (removed != null) { 18963 for (int j=0; j<removed.size(); j++) { 18964 PreferredActivity pa = removed.get(j); 18965 pir.removeFilter(pa); 18966 } 18967 changed = true; 18968 } 18969 } 18970 if (changed) { 18971 postPreferredActivityChangedBroadcast(userId); 18972 } 18973 return changed; 18974 } 18975 18976 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18977 private void clearIntentFilterVerificationsLPw(int userId) { 18978 final int packageCount = mPackages.size(); 18979 for (int i = 0; i < packageCount; i++) { 18980 PackageParser.Package pkg = mPackages.valueAt(i); 18981 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 18982 } 18983 } 18984 18985 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 18986 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 18987 if (userId == UserHandle.USER_ALL) { 18988 if (mSettings.removeIntentFilterVerificationLPw(packageName, 18989 sUserManager.getUserIds())) { 18990 for (int oneUserId : sUserManager.getUserIds()) { 18991 scheduleWritePackageRestrictionsLocked(oneUserId); 18992 } 18993 } 18994 } else { 18995 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 18996 scheduleWritePackageRestrictionsLocked(userId); 18997 } 18998 } 18999 } 19000 19001 void clearDefaultBrowserIfNeeded(String packageName) { 19002 for (int oneUserId : sUserManager.getUserIds()) { 19003 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 19004 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 19005 if (packageName.equals(defaultBrowserPackageName)) { 19006 setDefaultBrowserPackageName(null, oneUserId); 19007 } 19008 } 19009 } 19010 19011 @Override 19012 public void resetApplicationPreferences(int userId) { 19013 mContext.enforceCallingOrSelfPermission( 19014 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 19015 final long identity = Binder.clearCallingIdentity(); 19016 // writer 19017 try { 19018 synchronized (mPackages) { 19019 clearPackagePreferredActivitiesLPw(null, userId); 19020 mSettings.applyDefaultPreferredAppsLPw(this, userId); 19021 // TODO: We have to reset the default SMS and Phone. This requires 19022 // significant refactoring to keep all default apps in the package 19023 // manager (cleaner but more work) or have the services provide 19024 // callbacks to the package manager to request a default app reset. 19025 applyFactoryDefaultBrowserLPw(userId); 19026 clearIntentFilterVerificationsLPw(userId); 19027 primeDomainVerificationsLPw(userId); 19028 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 19029 scheduleWritePackageRestrictionsLocked(userId); 19030 } 19031 resetNetworkPolicies(userId); 19032 } finally { 19033 Binder.restoreCallingIdentity(identity); 19034 } 19035 } 19036 19037 @Override 19038 public int getPreferredActivities(List<IntentFilter> outFilters, 19039 List<ComponentName> outActivities, String packageName) { 19040 19041 int num = 0; 19042 final int userId = UserHandle.getCallingUserId(); 19043 // reader 19044 synchronized (mPackages) { 19045 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 19046 if (pir != null) { 19047 final Iterator<PreferredActivity> it = pir.filterIterator(); 19048 while (it.hasNext()) { 19049 final PreferredActivity pa = it.next(); 19050 if (packageName == null 19051 || (pa.mPref.mComponent.getPackageName().equals(packageName) 19052 && pa.mPref.mAlways)) { 19053 if (outFilters != null) { 19054 outFilters.add(new IntentFilter(pa)); 19055 } 19056 if (outActivities != null) { 19057 outActivities.add(pa.mPref.mComponent); 19058 } 19059 } 19060 } 19061 } 19062 } 19063 19064 return num; 19065 } 19066 19067 @Override 19068 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 19069 int userId) { 19070 int callingUid = Binder.getCallingUid(); 19071 if (callingUid != Process.SYSTEM_UID) { 19072 throw new SecurityException( 19073 "addPersistentPreferredActivity can only be run by the system"); 19074 } 19075 if (filter.countActions() == 0) { 19076 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 19077 return; 19078 } 19079 synchronized (mPackages) { 19080 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 19081 ":"); 19082 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 19083 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 19084 new PersistentPreferredActivity(filter, activity)); 19085 scheduleWritePackageRestrictionsLocked(userId); 19086 postPreferredActivityChangedBroadcast(userId); 19087 } 19088 } 19089 19090 @Override 19091 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 19092 int callingUid = Binder.getCallingUid(); 19093 if (callingUid != Process.SYSTEM_UID) { 19094 throw new SecurityException( 19095 "clearPackagePersistentPreferredActivities can only be run by the system"); 19096 } 19097 ArrayList<PersistentPreferredActivity> removed = null; 19098 boolean changed = false; 19099 synchronized (mPackages) { 19100 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 19101 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 19102 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 19103 .valueAt(i); 19104 if (userId != thisUserId) { 19105 continue; 19106 } 19107 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 19108 while (it.hasNext()) { 19109 PersistentPreferredActivity ppa = it.next(); 19110 // Mark entry for removal only if it matches the package name. 19111 if (ppa.mComponent.getPackageName().equals(packageName)) { 19112 if (removed == null) { 19113 removed = new ArrayList<PersistentPreferredActivity>(); 19114 } 19115 removed.add(ppa); 19116 } 19117 } 19118 if (removed != null) { 19119 for (int j=0; j<removed.size(); j++) { 19120 PersistentPreferredActivity ppa = removed.get(j); 19121 ppir.removeFilter(ppa); 19122 } 19123 changed = true; 19124 } 19125 } 19126 19127 if (changed) { 19128 scheduleWritePackageRestrictionsLocked(userId); 19129 postPreferredActivityChangedBroadcast(userId); 19130 } 19131 } 19132 } 19133 19134 /** 19135 * Common machinery for picking apart a restored XML blob and passing 19136 * it to a caller-supplied functor to be applied to the running system. 19137 */ 19138 private void restoreFromXml(XmlPullParser parser, int userId, 19139 String expectedStartTag, BlobXmlRestorer functor) 19140 throws IOException, XmlPullParserException { 19141 int type; 19142 while ((type = parser.next()) != XmlPullParser.START_TAG 19143 && type != XmlPullParser.END_DOCUMENT) { 19144 } 19145 if (type != XmlPullParser.START_TAG) { 19146 // oops didn't find a start tag?! 19147 if (DEBUG_BACKUP) { 19148 Slog.e(TAG, "Didn't find start tag during restore"); 19149 } 19150 return; 19151 } 19152Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 19153 // this is supposed to be TAG_PREFERRED_BACKUP 19154 if (!expectedStartTag.equals(parser.getName())) { 19155 if (DEBUG_BACKUP) { 19156 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 19157 } 19158 return; 19159 } 19160 19161 // skip interfering stuff, then we're aligned with the backing implementation 19162 while ((type = parser.next()) == XmlPullParser.TEXT) { } 19163Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 19164 functor.apply(parser, userId); 19165 } 19166 19167 private interface BlobXmlRestorer { 19168 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 19169 } 19170 19171 /** 19172 * Non-Binder method, support for the backup/restore mechanism: write the 19173 * full set of preferred activities in its canonical XML format. Returns the 19174 * XML output as a byte array, or null if there is none. 19175 */ 19176 @Override 19177 public byte[] getPreferredActivityBackup(int userId) { 19178 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19179 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 19180 } 19181 19182 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19183 try { 19184 final XmlSerializer serializer = new FastXmlSerializer(); 19185 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19186 serializer.startDocument(null, true); 19187 serializer.startTag(null, TAG_PREFERRED_BACKUP); 19188 19189 synchronized (mPackages) { 19190 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 19191 } 19192 19193 serializer.endTag(null, TAG_PREFERRED_BACKUP); 19194 serializer.endDocument(); 19195 serializer.flush(); 19196 } catch (Exception e) { 19197 if (DEBUG_BACKUP) { 19198 Slog.e(TAG, "Unable to write preferred activities for backup", e); 19199 } 19200 return null; 19201 } 19202 19203 return dataStream.toByteArray(); 19204 } 19205 19206 @Override 19207 public void restorePreferredActivities(byte[] backup, int userId) { 19208 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19209 throw new SecurityException("Only the system may call restorePreferredActivities()"); 19210 } 19211 19212 try { 19213 final XmlPullParser parser = Xml.newPullParser(); 19214 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19215 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 19216 new BlobXmlRestorer() { 19217 @Override 19218 public void apply(XmlPullParser parser, int userId) 19219 throws XmlPullParserException, IOException { 19220 synchronized (mPackages) { 19221 mSettings.readPreferredActivitiesLPw(parser, userId); 19222 } 19223 } 19224 } ); 19225 } catch (Exception e) { 19226 if (DEBUG_BACKUP) { 19227 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19228 } 19229 } 19230 } 19231 19232 /** 19233 * Non-Binder method, support for the backup/restore mechanism: write the 19234 * default browser (etc) settings in its canonical XML format. Returns the default 19235 * browser XML representation as a byte array, or null if there is none. 19236 */ 19237 @Override 19238 public byte[] getDefaultAppsBackup(int userId) { 19239 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19240 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 19241 } 19242 19243 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19244 try { 19245 final XmlSerializer serializer = new FastXmlSerializer(); 19246 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19247 serializer.startDocument(null, true); 19248 serializer.startTag(null, TAG_DEFAULT_APPS); 19249 19250 synchronized (mPackages) { 19251 mSettings.writeDefaultAppsLPr(serializer, userId); 19252 } 19253 19254 serializer.endTag(null, TAG_DEFAULT_APPS); 19255 serializer.endDocument(); 19256 serializer.flush(); 19257 } catch (Exception e) { 19258 if (DEBUG_BACKUP) { 19259 Slog.e(TAG, "Unable to write default apps for backup", e); 19260 } 19261 return null; 19262 } 19263 19264 return dataStream.toByteArray(); 19265 } 19266 19267 @Override 19268 public void restoreDefaultApps(byte[] backup, int userId) { 19269 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19270 throw new SecurityException("Only the system may call restoreDefaultApps()"); 19271 } 19272 19273 try { 19274 final XmlPullParser parser = Xml.newPullParser(); 19275 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19276 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 19277 new BlobXmlRestorer() { 19278 @Override 19279 public void apply(XmlPullParser parser, int userId) 19280 throws XmlPullParserException, IOException { 19281 synchronized (mPackages) { 19282 mSettings.readDefaultAppsLPw(parser, userId); 19283 } 19284 } 19285 } ); 19286 } catch (Exception e) { 19287 if (DEBUG_BACKUP) { 19288 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 19289 } 19290 } 19291 } 19292 19293 @Override 19294 public byte[] getIntentFilterVerificationBackup(int userId) { 19295 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19296 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 19297 } 19298 19299 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19300 try { 19301 final XmlSerializer serializer = new FastXmlSerializer(); 19302 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19303 serializer.startDocument(null, true); 19304 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 19305 19306 synchronized (mPackages) { 19307 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 19308 } 19309 19310 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 19311 serializer.endDocument(); 19312 serializer.flush(); 19313 } catch (Exception e) { 19314 if (DEBUG_BACKUP) { 19315 Slog.e(TAG, "Unable to write default apps for backup", e); 19316 } 19317 return null; 19318 } 19319 19320 return dataStream.toByteArray(); 19321 } 19322 19323 @Override 19324 public void restoreIntentFilterVerification(byte[] backup, int userId) { 19325 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19326 throw new SecurityException("Only the system may call restorePreferredActivities()"); 19327 } 19328 19329 try { 19330 final XmlPullParser parser = Xml.newPullParser(); 19331 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19332 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 19333 new BlobXmlRestorer() { 19334 @Override 19335 public void apply(XmlPullParser parser, int userId) 19336 throws XmlPullParserException, IOException { 19337 synchronized (mPackages) { 19338 mSettings.readAllDomainVerificationsLPr(parser, userId); 19339 mSettings.writeLPr(); 19340 } 19341 } 19342 } ); 19343 } catch (Exception e) { 19344 if (DEBUG_BACKUP) { 19345 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19346 } 19347 } 19348 } 19349 19350 @Override 19351 public byte[] getPermissionGrantBackup(int userId) { 19352 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19353 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 19354 } 19355 19356 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 19357 try { 19358 final XmlSerializer serializer = new FastXmlSerializer(); 19359 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 19360 serializer.startDocument(null, true); 19361 serializer.startTag(null, TAG_PERMISSION_BACKUP); 19362 19363 synchronized (mPackages) { 19364 serializeRuntimePermissionGrantsLPr(serializer, userId); 19365 } 19366 19367 serializer.endTag(null, TAG_PERMISSION_BACKUP); 19368 serializer.endDocument(); 19369 serializer.flush(); 19370 } catch (Exception e) { 19371 if (DEBUG_BACKUP) { 19372 Slog.e(TAG, "Unable to write default apps for backup", e); 19373 } 19374 return null; 19375 } 19376 19377 return dataStream.toByteArray(); 19378 } 19379 19380 @Override 19381 public void restorePermissionGrants(byte[] backup, int userId) { 19382 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 19383 throw new SecurityException("Only the system may call restorePermissionGrants()"); 19384 } 19385 19386 try { 19387 final XmlPullParser parser = Xml.newPullParser(); 19388 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 19389 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 19390 new BlobXmlRestorer() { 19391 @Override 19392 public void apply(XmlPullParser parser, int userId) 19393 throws XmlPullParserException, IOException { 19394 synchronized (mPackages) { 19395 processRestoredPermissionGrantsLPr(parser, userId); 19396 } 19397 } 19398 } ); 19399 } catch (Exception e) { 19400 if (DEBUG_BACKUP) { 19401 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 19402 } 19403 } 19404 } 19405 19406 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 19407 throws IOException { 19408 serializer.startTag(null, TAG_ALL_GRANTS); 19409 19410 final int N = mSettings.mPackages.size(); 19411 for (int i = 0; i < N; i++) { 19412 final PackageSetting ps = mSettings.mPackages.valueAt(i); 19413 boolean pkgGrantsKnown = false; 19414 19415 PermissionsState packagePerms = ps.getPermissionsState(); 19416 19417 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 19418 final int grantFlags = state.getFlags(); 19419 // only look at grants that are not system/policy fixed 19420 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 19421 final boolean isGranted = state.isGranted(); 19422 // And only back up the user-twiddled state bits 19423 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 19424 final String packageName = mSettings.mPackages.keyAt(i); 19425 if (!pkgGrantsKnown) { 19426 serializer.startTag(null, TAG_GRANT); 19427 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 19428 pkgGrantsKnown = true; 19429 } 19430 19431 final boolean userSet = 19432 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 19433 final boolean userFixed = 19434 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 19435 final boolean revoke = 19436 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 19437 19438 serializer.startTag(null, TAG_PERMISSION); 19439 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 19440 if (isGranted) { 19441 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 19442 } 19443 if (userSet) { 19444 serializer.attribute(null, ATTR_USER_SET, "true"); 19445 } 19446 if (userFixed) { 19447 serializer.attribute(null, ATTR_USER_FIXED, "true"); 19448 } 19449 if (revoke) { 19450 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 19451 } 19452 serializer.endTag(null, TAG_PERMISSION); 19453 } 19454 } 19455 } 19456 19457 if (pkgGrantsKnown) { 19458 serializer.endTag(null, TAG_GRANT); 19459 } 19460 } 19461 19462 serializer.endTag(null, TAG_ALL_GRANTS); 19463 } 19464 19465 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 19466 throws XmlPullParserException, IOException { 19467 String pkgName = null; 19468 int outerDepth = parser.getDepth(); 19469 int type; 19470 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 19471 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 19472 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 19473 continue; 19474 } 19475 19476 final String tagName = parser.getName(); 19477 if (tagName.equals(TAG_GRANT)) { 19478 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 19479 if (DEBUG_BACKUP) { 19480 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 19481 } 19482 } else if (tagName.equals(TAG_PERMISSION)) { 19483 19484 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 19485 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 19486 19487 int newFlagSet = 0; 19488 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 19489 newFlagSet |= FLAG_PERMISSION_USER_SET; 19490 } 19491 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 19492 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 19493 } 19494 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 19495 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 19496 } 19497 if (DEBUG_BACKUP) { 19498 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 19499 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 19500 } 19501 final PackageSetting ps = mSettings.mPackages.get(pkgName); 19502 if (ps != null) { 19503 // Already installed so we apply the grant immediately 19504 if (DEBUG_BACKUP) { 19505 Slog.v(TAG, " + already installed; applying"); 19506 } 19507 PermissionsState perms = ps.getPermissionsState(); 19508 BasePermission bp = mSettings.mPermissions.get(permName); 19509 if (bp != null) { 19510 if (isGranted) { 19511 perms.grantRuntimePermission(bp, userId); 19512 } 19513 if (newFlagSet != 0) { 19514 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 19515 } 19516 } 19517 } else { 19518 // Need to wait for post-restore install to apply the grant 19519 if (DEBUG_BACKUP) { 19520 Slog.v(TAG, " - not yet installed; saving for later"); 19521 } 19522 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 19523 isGranted, newFlagSet, userId); 19524 } 19525 } else { 19526 PackageManagerService.reportSettingsProblem(Log.WARN, 19527 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 19528 XmlUtils.skipCurrentTag(parser); 19529 } 19530 } 19531 19532 scheduleWriteSettingsLocked(); 19533 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 19534 } 19535 19536 @Override 19537 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 19538 int sourceUserId, int targetUserId, int flags) { 19539 mContext.enforceCallingOrSelfPermission( 19540 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 19541 int callingUid = Binder.getCallingUid(); 19542 enforceOwnerRights(ownerPackage, callingUid); 19543 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 19544 if (intentFilter.countActions() == 0) { 19545 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 19546 return; 19547 } 19548 synchronized (mPackages) { 19549 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 19550 ownerPackage, targetUserId, flags); 19551 CrossProfileIntentResolver resolver = 19552 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 19553 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 19554 // We have all those whose filter is equal. Now checking if the rest is equal as well. 19555 if (existing != null) { 19556 int size = existing.size(); 19557 for (int i = 0; i < size; i++) { 19558 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 19559 return; 19560 } 19561 } 19562 } 19563 resolver.addFilter(newFilter); 19564 scheduleWritePackageRestrictionsLocked(sourceUserId); 19565 } 19566 } 19567 19568 @Override 19569 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 19570 mContext.enforceCallingOrSelfPermission( 19571 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 19572 int callingUid = Binder.getCallingUid(); 19573 enforceOwnerRights(ownerPackage, callingUid); 19574 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 19575 synchronized (mPackages) { 19576 CrossProfileIntentResolver resolver = 19577 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 19578 ArraySet<CrossProfileIntentFilter> set = 19579 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 19580 for (CrossProfileIntentFilter filter : set) { 19581 if (filter.getOwnerPackage().equals(ownerPackage)) { 19582 resolver.removeFilter(filter); 19583 } 19584 } 19585 scheduleWritePackageRestrictionsLocked(sourceUserId); 19586 } 19587 } 19588 19589 // Enforcing that callingUid is owning pkg on userId 19590 private void enforceOwnerRights(String pkg, int callingUid) { 19591 // The system owns everything. 19592 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 19593 return; 19594 } 19595 int callingUserId = UserHandle.getUserId(callingUid); 19596 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 19597 if (pi == null) { 19598 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 19599 + callingUserId); 19600 } 19601 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 19602 throw new SecurityException("Calling uid " + callingUid 19603 + " does not own package " + pkg); 19604 } 19605 } 19606 19607 @Override 19608 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 19609 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 19610 } 19611 19612 /** 19613 * Report the 'Home' activity which is currently set as "always use this one". If non is set 19614 * then reports the most likely home activity or null if there are more than one. 19615 */ 19616 public ComponentName getDefaultHomeActivity(int userId) { 19617 List<ResolveInfo> allHomeCandidates = new ArrayList<>(); 19618 ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId); 19619 if (cn != null) { 19620 return cn; 19621 } 19622 19623 // Find the launcher with the highest priority and return that component if there are no 19624 // other home activity with the same priority. 19625 int lastPriority = Integer.MIN_VALUE; 19626 ComponentName lastComponent = null; 19627 final int size = allHomeCandidates.size(); 19628 for (int i = 0; i < size; i++) { 19629 final ResolveInfo ri = allHomeCandidates.get(i); 19630 if (ri.priority > lastPriority) { 19631 lastComponent = ri.activityInfo.getComponentName(); 19632 lastPriority = ri.priority; 19633 } else if (ri.priority == lastPriority) { 19634 // Two components found with same priority. 19635 lastComponent = null; 19636 } 19637 } 19638 return lastComponent; 19639 } 19640 19641 private Intent getHomeIntent() { 19642 Intent intent = new Intent(Intent.ACTION_MAIN); 19643 intent.addCategory(Intent.CATEGORY_HOME); 19644 intent.addCategory(Intent.CATEGORY_DEFAULT); 19645 return intent; 19646 } 19647 19648 private IntentFilter getHomeFilter() { 19649 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 19650 filter.addCategory(Intent.CATEGORY_HOME); 19651 filter.addCategory(Intent.CATEGORY_DEFAULT); 19652 return filter; 19653 } 19654 19655 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 19656 int userId) { 19657 Intent intent = getHomeIntent(); 19658 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 19659 PackageManager.GET_META_DATA, userId); 19660 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 19661 true, false, false, userId); 19662 19663 allHomeCandidates.clear(); 19664 if (list != null) { 19665 for (ResolveInfo ri : list) { 19666 allHomeCandidates.add(ri); 19667 } 19668 } 19669 return (preferred == null || preferred.activityInfo == null) 19670 ? null 19671 : new ComponentName(preferred.activityInfo.packageName, 19672 preferred.activityInfo.name); 19673 } 19674 19675 @Override 19676 public void setHomeActivity(ComponentName comp, int userId) { 19677 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 19678 getHomeActivitiesAsUser(homeActivities, userId); 19679 19680 boolean found = false; 19681 19682 final int size = homeActivities.size(); 19683 final ComponentName[] set = new ComponentName[size]; 19684 for (int i = 0; i < size; i++) { 19685 final ResolveInfo candidate = homeActivities.get(i); 19686 final ActivityInfo info = candidate.activityInfo; 19687 final ComponentName activityName = new ComponentName(info.packageName, info.name); 19688 set[i] = activityName; 19689 if (!found && activityName.equals(comp)) { 19690 found = true; 19691 } 19692 } 19693 if (!found) { 19694 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 19695 + userId); 19696 } 19697 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 19698 set, comp, userId); 19699 } 19700 19701 private @Nullable String getSetupWizardPackageName() { 19702 final Intent intent = new Intent(Intent.ACTION_MAIN); 19703 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 19704 19705 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 19706 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 19707 | MATCH_DISABLED_COMPONENTS, 19708 UserHandle.myUserId()); 19709 if (matches.size() == 1) { 19710 return matches.get(0).getComponentInfo().packageName; 19711 } else { 19712 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 19713 + ": matches=" + matches); 19714 return null; 19715 } 19716 } 19717 19718 private @Nullable String getStorageManagerPackageName() { 19719 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); 19720 19721 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 19722 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 19723 | MATCH_DISABLED_COMPONENTS, 19724 UserHandle.myUserId()); 19725 if (matches.size() == 1) { 19726 return matches.get(0).getComponentInfo().packageName; 19727 } else { 19728 Slog.e(TAG, "There should probably be exactly one storage manager; found " 19729 + matches.size() + ": matches=" + matches); 19730 return null; 19731 } 19732 } 19733 19734 @Override 19735 public void setApplicationEnabledSetting(String appPackageName, 19736 int newState, int flags, int userId, String callingPackage) { 19737 if (!sUserManager.exists(userId)) return; 19738 if (callingPackage == null) { 19739 callingPackage = Integer.toString(Binder.getCallingUid()); 19740 } 19741 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 19742 } 19743 19744 @Override 19745 public void setUpdateAvailable(String packageName, boolean updateAvailable) { 19746 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 19747 synchronized (mPackages) { 19748 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 19749 if (pkgSetting != null) { 19750 pkgSetting.setUpdateAvailable(updateAvailable); 19751 } 19752 } 19753 } 19754 19755 @Override 19756 public void setComponentEnabledSetting(ComponentName componentName, 19757 int newState, int flags, int userId) { 19758 if (!sUserManager.exists(userId)) return; 19759 setEnabledSetting(componentName.getPackageName(), 19760 componentName.getClassName(), newState, flags, userId, null); 19761 } 19762 19763 private void setEnabledSetting(final String packageName, String className, int newState, 19764 final int flags, int userId, String callingPackage) { 19765 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 19766 || newState == COMPONENT_ENABLED_STATE_ENABLED 19767 || newState == COMPONENT_ENABLED_STATE_DISABLED 19768 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 19769 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 19770 throw new IllegalArgumentException("Invalid new component state: " 19771 + newState); 19772 } 19773 PackageSetting pkgSetting; 19774 final int uid = Binder.getCallingUid(); 19775 final int permission; 19776 if (uid == Process.SYSTEM_UID) { 19777 permission = PackageManager.PERMISSION_GRANTED; 19778 } else { 19779 permission = mContext.checkCallingOrSelfPermission( 19780 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 19781 } 19782 enforceCrossUserPermission(uid, userId, 19783 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 19784 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 19785 boolean sendNow = false; 19786 boolean isApp = (className == null); 19787 String componentName = isApp ? packageName : className; 19788 int packageUid = -1; 19789 ArrayList<String> components; 19790 19791 // writer 19792 synchronized (mPackages) { 19793 pkgSetting = mSettings.mPackages.get(packageName); 19794 if (pkgSetting == null) { 19795 if (className == null) { 19796 throw new IllegalArgumentException("Unknown package: " + packageName); 19797 } 19798 throw new IllegalArgumentException( 19799 "Unknown component: " + packageName + "/" + className); 19800 } 19801 } 19802 19803 // Limit who can change which apps 19804 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 19805 // Don't allow apps that don't have permission to modify other apps 19806 if (!allowedByPermission) { 19807 throw new SecurityException( 19808 "Permission Denial: attempt to change component state from pid=" 19809 + Binder.getCallingPid() 19810 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 19811 } 19812 // Don't allow changing protected packages. 19813 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 19814 throw new SecurityException("Cannot disable a protected package: " + packageName); 19815 } 19816 } 19817 19818 synchronized (mPackages) { 19819 if (uid == Process.SHELL_UID 19820 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { 19821 // Shell can only change whole packages between ENABLED and DISABLED_USER states 19822 // unless it is a test package. 19823 int oldState = pkgSetting.getEnabled(userId); 19824 if (className == null 19825 && 19826 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 19827 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 19828 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 19829 && 19830 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 19831 || newState == COMPONENT_ENABLED_STATE_DEFAULT 19832 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 19833 // ok 19834 } else { 19835 throw new SecurityException( 19836 "Shell cannot change component state for " + packageName + "/" 19837 + className + " to " + newState); 19838 } 19839 } 19840 if (className == null) { 19841 // We're dealing with an application/package level state change 19842 if (pkgSetting.getEnabled(userId) == newState) { 19843 // Nothing to do 19844 return; 19845 } 19846 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 19847 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 19848 // Don't care about who enables an app. 19849 callingPackage = null; 19850 } 19851 pkgSetting.setEnabled(newState, userId, callingPackage); 19852 // pkgSetting.pkg.mSetEnabled = newState; 19853 } else { 19854 // We're dealing with a component level state change 19855 // First, verify that this is a valid class name. 19856 PackageParser.Package pkg = pkgSetting.pkg; 19857 if (pkg == null || !pkg.hasComponentClassName(className)) { 19858 if (pkg != null && 19859 pkg.applicationInfo.targetSdkVersion >= 19860 Build.VERSION_CODES.JELLY_BEAN) { 19861 throw new IllegalArgumentException("Component class " + className 19862 + " does not exist in " + packageName); 19863 } else { 19864 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 19865 + className + " does not exist in " + packageName); 19866 } 19867 } 19868 switch (newState) { 19869 case COMPONENT_ENABLED_STATE_ENABLED: 19870 if (!pkgSetting.enableComponentLPw(className, userId)) { 19871 return; 19872 } 19873 break; 19874 case COMPONENT_ENABLED_STATE_DISABLED: 19875 if (!pkgSetting.disableComponentLPw(className, userId)) { 19876 return; 19877 } 19878 break; 19879 case COMPONENT_ENABLED_STATE_DEFAULT: 19880 if (!pkgSetting.restoreComponentLPw(className, userId)) { 19881 return; 19882 } 19883 break; 19884 default: 19885 Slog.e(TAG, "Invalid new component state: " + newState); 19886 return; 19887 } 19888 } 19889 scheduleWritePackageRestrictionsLocked(userId); 19890 updateSequenceNumberLP(packageName, new int[] { userId }); 19891 final long callingId = Binder.clearCallingIdentity(); 19892 try { 19893 updateInstantAppInstallerLocked(); 19894 } finally { 19895 Binder.restoreCallingIdentity(callingId); 19896 } 19897 components = mPendingBroadcasts.get(userId, packageName); 19898 final boolean newPackage = components == null; 19899 if (newPackage) { 19900 components = new ArrayList<String>(); 19901 } 19902 if (!components.contains(componentName)) { 19903 components.add(componentName); 19904 } 19905 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 19906 sendNow = true; 19907 // Purge entry from pending broadcast list if another one exists already 19908 // since we are sending one right away. 19909 mPendingBroadcasts.remove(userId, packageName); 19910 } else { 19911 if (newPackage) { 19912 mPendingBroadcasts.put(userId, packageName, components); 19913 } 19914 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 19915 // Schedule a message 19916 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 19917 } 19918 } 19919 } 19920 19921 long callingId = Binder.clearCallingIdentity(); 19922 try { 19923 if (sendNow) { 19924 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 19925 sendPackageChangedBroadcast(packageName, 19926 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 19927 } 19928 } finally { 19929 Binder.restoreCallingIdentity(callingId); 19930 } 19931 } 19932 19933 @Override 19934 public void flushPackageRestrictionsAsUser(int userId) { 19935 if (!sUserManager.exists(userId)) { 19936 return; 19937 } 19938 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 19939 false /* checkShell */, "flushPackageRestrictions"); 19940 synchronized (mPackages) { 19941 mSettings.writePackageRestrictionsLPr(userId); 19942 mDirtyUsers.remove(userId); 19943 if (mDirtyUsers.isEmpty()) { 19944 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 19945 } 19946 } 19947 } 19948 19949 private void sendPackageChangedBroadcast(String packageName, 19950 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 19951 if (DEBUG_INSTALL) 19952 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 19953 + componentNames); 19954 Bundle extras = new Bundle(4); 19955 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 19956 String nameList[] = new String[componentNames.size()]; 19957 componentNames.toArray(nameList); 19958 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 19959 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 19960 extras.putInt(Intent.EXTRA_UID, packageUid); 19961 // If this is not reporting a change of the overall package, then only send it 19962 // to registered receivers. We don't want to launch a swath of apps for every 19963 // little component state change. 19964 final int flags = !componentNames.contains(packageName) 19965 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 19966 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 19967 new int[] {UserHandle.getUserId(packageUid)}); 19968 } 19969 19970 @Override 19971 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 19972 if (!sUserManager.exists(userId)) return; 19973 final int uid = Binder.getCallingUid(); 19974 final int permission = mContext.checkCallingOrSelfPermission( 19975 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 19976 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 19977 enforceCrossUserPermission(uid, userId, 19978 true /* requireFullPermission */, true /* checkShell */, "stop package"); 19979 // writer 19980 synchronized (mPackages) { 19981 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 19982 allowedByPermission, uid, userId)) { 19983 scheduleWritePackageRestrictionsLocked(userId); 19984 } 19985 } 19986 } 19987 19988 @Override 19989 public String getInstallerPackageName(String packageName) { 19990 // reader 19991 synchronized (mPackages) { 19992 return mSettings.getInstallerPackageNameLPr(packageName); 19993 } 19994 } 19995 19996 public boolean isOrphaned(String packageName) { 19997 // reader 19998 synchronized (mPackages) { 19999 return mSettings.isOrphaned(packageName); 20000 } 20001 } 20002 20003 @Override 20004 public int getApplicationEnabledSetting(String packageName, int userId) { 20005 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 20006 int uid = Binder.getCallingUid(); 20007 enforceCrossUserPermission(uid, userId, 20008 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 20009 // reader 20010 synchronized (mPackages) { 20011 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 20012 } 20013 } 20014 20015 @Override 20016 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 20017 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 20018 int uid = Binder.getCallingUid(); 20019 enforceCrossUserPermission(uid, userId, 20020 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 20021 // reader 20022 synchronized (mPackages) { 20023 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 20024 } 20025 } 20026 20027 @Override 20028 public void enterSafeMode() { 20029 enforceSystemOrRoot("Only the system can request entering safe mode"); 20030 20031 if (!mSystemReady) { 20032 mSafeMode = true; 20033 } 20034 } 20035 20036 @Override 20037 public void systemReady() { 20038 mSystemReady = true; 20039 20040 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 20041 // disabled after already being started. 20042 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 20043 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 20044 20045 // Read the compatibilty setting when the system is ready. 20046 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 20047 mContext.getContentResolver(), 20048 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 20049 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 20050 if (DEBUG_SETTINGS) { 20051 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 20052 } 20053 20054 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 20055 20056 synchronized (mPackages) { 20057 // Verify that all of the preferred activity components actually 20058 // exist. It is possible for applications to be updated and at 20059 // that point remove a previously declared activity component that 20060 // had been set as a preferred activity. We try to clean this up 20061 // the next time we encounter that preferred activity, but it is 20062 // possible for the user flow to never be able to return to that 20063 // situation so here we do a sanity check to make sure we haven't 20064 // left any junk around. 20065 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 20066 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 20067 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 20068 removed.clear(); 20069 for (PreferredActivity pa : pir.filterSet()) { 20070 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 20071 removed.add(pa); 20072 } 20073 } 20074 if (removed.size() > 0) { 20075 for (int r=0; r<removed.size(); r++) { 20076 PreferredActivity pa = removed.get(r); 20077 Slog.w(TAG, "Removing dangling preferred activity: " 20078 + pa.mPref.mComponent); 20079 pir.removeFilter(pa); 20080 } 20081 mSettings.writePackageRestrictionsLPr( 20082 mSettings.mPreferredActivities.keyAt(i)); 20083 } 20084 } 20085 20086 for (int userId : UserManagerService.getInstance().getUserIds()) { 20087 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 20088 grantPermissionsUserIds = ArrayUtils.appendInt( 20089 grantPermissionsUserIds, userId); 20090 } 20091 } 20092 } 20093 sUserManager.systemReady(); 20094 20095 // If we upgraded grant all default permissions before kicking off. 20096 for (int userId : grantPermissionsUserIds) { 20097 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 20098 } 20099 20100 // If we did not grant default permissions, we preload from this the 20101 // default permission exceptions lazily to ensure we don't hit the 20102 // disk on a new user creation. 20103 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 20104 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 20105 } 20106 20107 // Kick off any messages waiting for system ready 20108 if (mPostSystemReadyMessages != null) { 20109 for (Message msg : mPostSystemReadyMessages) { 20110 msg.sendToTarget(); 20111 } 20112 mPostSystemReadyMessages = null; 20113 } 20114 20115 // Watch for external volumes that come and go over time 20116 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20117 storage.registerListener(mStorageListener); 20118 20119 mInstallerService.systemReady(); 20120 mPackageDexOptimizer.systemReady(); 20121 20122 StorageManagerInternal StorageManagerInternal = LocalServices.getService( 20123 StorageManagerInternal.class); 20124 StorageManagerInternal.addExternalStoragePolicy( 20125 new StorageManagerInternal.ExternalStorageMountPolicy() { 20126 @Override 20127 public int getMountMode(int uid, String packageName) { 20128 if (Process.isIsolated(uid)) { 20129 return Zygote.MOUNT_EXTERNAL_NONE; 20130 } 20131 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 20132 return Zygote.MOUNT_EXTERNAL_DEFAULT; 20133 } 20134 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 20135 return Zygote.MOUNT_EXTERNAL_DEFAULT; 20136 } 20137 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 20138 return Zygote.MOUNT_EXTERNAL_READ; 20139 } 20140 return Zygote.MOUNT_EXTERNAL_WRITE; 20141 } 20142 20143 @Override 20144 public boolean hasExternalStorage(int uid, String packageName) { 20145 return true; 20146 } 20147 }); 20148 20149 // Now that we're mostly running, clean up stale users and apps 20150 sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 20151 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 20152 20153 if (mPrivappPermissionsViolations != null) { 20154 Slog.wtf(TAG,"Signature|privileged permissions not in " 20155 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations); 20156 mPrivappPermissionsViolations = null; 20157 } 20158 } 20159 20160 public void waitForAppDataPrepared() { 20161 if (mPrepareAppDataFuture == null) { 20162 return; 20163 } 20164 ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData"); 20165 mPrepareAppDataFuture = null; 20166 } 20167 20168 @Override 20169 public boolean isSafeMode() { 20170 return mSafeMode; 20171 } 20172 20173 @Override 20174 public boolean hasSystemUidErrors() { 20175 return mHasSystemUidErrors; 20176 } 20177 20178 static String arrayToString(int[] array) { 20179 StringBuffer buf = new StringBuffer(128); 20180 buf.append('['); 20181 if (array != null) { 20182 for (int i=0; i<array.length; i++) { 20183 if (i > 0) buf.append(", "); 20184 buf.append(array[i]); 20185 } 20186 } 20187 buf.append(']'); 20188 return buf.toString(); 20189 } 20190 20191 static class DumpState { 20192 public static final int DUMP_LIBS = 1 << 0; 20193 public static final int DUMP_FEATURES = 1 << 1; 20194 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 20195 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 20196 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 20197 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 20198 public static final int DUMP_PERMISSIONS = 1 << 6; 20199 public static final int DUMP_PACKAGES = 1 << 7; 20200 public static final int DUMP_SHARED_USERS = 1 << 8; 20201 public static final int DUMP_MESSAGES = 1 << 9; 20202 public static final int DUMP_PROVIDERS = 1 << 10; 20203 public static final int DUMP_VERIFIERS = 1 << 11; 20204 public static final int DUMP_PREFERRED = 1 << 12; 20205 public static final int DUMP_PREFERRED_XML = 1 << 13; 20206 public static final int DUMP_KEYSETS = 1 << 14; 20207 public static final int DUMP_VERSION = 1 << 15; 20208 public static final int DUMP_INSTALLS = 1 << 16; 20209 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 20210 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 20211 public static final int DUMP_FROZEN = 1 << 19; 20212 public static final int DUMP_DEXOPT = 1 << 20; 20213 public static final int DUMP_COMPILER_STATS = 1 << 21; 20214 public static final int DUMP_ENABLED_OVERLAYS = 1 << 22; 20215 20216 public static final int OPTION_SHOW_FILTERS = 1 << 0; 20217 20218 private int mTypes; 20219 20220 private int mOptions; 20221 20222 private boolean mTitlePrinted; 20223 20224 private SharedUserSetting mSharedUser; 20225 20226 public boolean isDumping(int type) { 20227 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 20228 return true; 20229 } 20230 20231 return (mTypes & type) != 0; 20232 } 20233 20234 public void setDump(int type) { 20235 mTypes |= type; 20236 } 20237 20238 public boolean isOptionEnabled(int option) { 20239 return (mOptions & option) != 0; 20240 } 20241 20242 public void setOptionEnabled(int option) { 20243 mOptions |= option; 20244 } 20245 20246 public boolean onTitlePrinted() { 20247 final boolean printed = mTitlePrinted; 20248 mTitlePrinted = true; 20249 return printed; 20250 } 20251 20252 public boolean getTitlePrinted() { 20253 return mTitlePrinted; 20254 } 20255 20256 public void setTitlePrinted(boolean enabled) { 20257 mTitlePrinted = enabled; 20258 } 20259 20260 public SharedUserSetting getSharedUser() { 20261 return mSharedUser; 20262 } 20263 20264 public void setSharedUser(SharedUserSetting user) { 20265 mSharedUser = user; 20266 } 20267 } 20268 20269 @Override 20270 public void onShellCommand(FileDescriptor in, FileDescriptor out, 20271 FileDescriptor err, String[] args, ShellCallback callback, 20272 ResultReceiver resultReceiver) { 20273 (new PackageManagerShellCommand(this)).exec( 20274 this, in, out, err, args, callback, resultReceiver); 20275 } 20276 20277 @Override 20278 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 20279 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 20280 != PackageManager.PERMISSION_GRANTED) { 20281 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 20282 + Binder.getCallingPid() 20283 + ", uid=" + Binder.getCallingUid() 20284 + " without permission " 20285 + android.Manifest.permission.DUMP); 20286 return; 20287 } 20288 20289 DumpState dumpState = new DumpState(); 20290 boolean fullPreferred = false; 20291 boolean checkin = false; 20292 20293 String packageName = null; 20294 ArraySet<String> permissionNames = null; 20295 20296 int opti = 0; 20297 while (opti < args.length) { 20298 String opt = args[opti]; 20299 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 20300 break; 20301 } 20302 opti++; 20303 20304 if ("-a".equals(opt)) { 20305 // Right now we only know how to print all. 20306 } else if ("-h".equals(opt)) { 20307 pw.println("Package manager dump options:"); 20308 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 20309 pw.println(" --checkin: dump for a checkin"); 20310 pw.println(" -f: print details of intent filters"); 20311 pw.println(" -h: print this help"); 20312 pw.println(" cmd may be one of:"); 20313 pw.println(" l[ibraries]: list known shared libraries"); 20314 pw.println(" f[eatures]: list device features"); 20315 pw.println(" k[eysets]: print known keysets"); 20316 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 20317 pw.println(" perm[issions]: dump permissions"); 20318 pw.println(" permission [name ...]: dump declaration and use of given permission"); 20319 pw.println(" pref[erred]: print preferred package settings"); 20320 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 20321 pw.println(" prov[iders]: dump content providers"); 20322 pw.println(" p[ackages]: dump installed packages"); 20323 pw.println(" s[hared-users]: dump shared user IDs"); 20324 pw.println(" m[essages]: print collected runtime messages"); 20325 pw.println(" v[erifiers]: print package verifier info"); 20326 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 20327 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 20328 pw.println(" version: print database version info"); 20329 pw.println(" write: write current settings now"); 20330 pw.println(" installs: details about install sessions"); 20331 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 20332 pw.println(" dexopt: dump dexopt state"); 20333 pw.println(" compiler-stats: dump compiler statistics"); 20334 pw.println(" enabled-overlays: dump list of enabled overlay packages"); 20335 pw.println(" <package.name>: info about given package"); 20336 return; 20337 } else if ("--checkin".equals(opt)) { 20338 checkin = true; 20339 } else if ("-f".equals(opt)) { 20340 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 20341 } else if ("--proto".equals(opt)) { 20342 dumpProto(fd); 20343 return; 20344 } else { 20345 pw.println("Unknown argument: " + opt + "; use -h for help"); 20346 } 20347 } 20348 20349 // Is the caller requesting to dump a particular piece of data? 20350 if (opti < args.length) { 20351 String cmd = args[opti]; 20352 opti++; 20353 // Is this a package name? 20354 if ("android".equals(cmd) || cmd.contains(".")) { 20355 packageName = cmd; 20356 // When dumping a single package, we always dump all of its 20357 // filter information since the amount of data will be reasonable. 20358 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 20359 } else if ("check-permission".equals(cmd)) { 20360 if (opti >= args.length) { 20361 pw.println("Error: check-permission missing permission argument"); 20362 return; 20363 } 20364 String perm = args[opti]; 20365 opti++; 20366 if (opti >= args.length) { 20367 pw.println("Error: check-permission missing package argument"); 20368 return; 20369 } 20370 20371 String pkg = args[opti]; 20372 opti++; 20373 int user = UserHandle.getUserId(Binder.getCallingUid()); 20374 if (opti < args.length) { 20375 try { 20376 user = Integer.parseInt(args[opti]); 20377 } catch (NumberFormatException e) { 20378 pw.println("Error: check-permission user argument is not a number: " 20379 + args[opti]); 20380 return; 20381 } 20382 } 20383 20384 // Normalize package name to handle renamed packages and static libs 20385 pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST); 20386 20387 pw.println(checkPermission(perm, pkg, user)); 20388 return; 20389 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 20390 dumpState.setDump(DumpState.DUMP_LIBS); 20391 } else if ("f".equals(cmd) || "features".equals(cmd)) { 20392 dumpState.setDump(DumpState.DUMP_FEATURES); 20393 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 20394 if (opti >= args.length) { 20395 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 20396 | DumpState.DUMP_SERVICE_RESOLVERS 20397 | DumpState.DUMP_RECEIVER_RESOLVERS 20398 | DumpState.DUMP_CONTENT_RESOLVERS); 20399 } else { 20400 while (opti < args.length) { 20401 String name = args[opti]; 20402 if ("a".equals(name) || "activity".equals(name)) { 20403 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 20404 } else if ("s".equals(name) || "service".equals(name)) { 20405 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 20406 } else if ("r".equals(name) || "receiver".equals(name)) { 20407 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 20408 } else if ("c".equals(name) || "content".equals(name)) { 20409 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 20410 } else { 20411 pw.println("Error: unknown resolver table type: " + name); 20412 return; 20413 } 20414 opti++; 20415 } 20416 } 20417 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 20418 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 20419 } else if ("permission".equals(cmd)) { 20420 if (opti >= args.length) { 20421 pw.println("Error: permission requires permission name"); 20422 return; 20423 } 20424 permissionNames = new ArraySet<>(); 20425 while (opti < args.length) { 20426 permissionNames.add(args[opti]); 20427 opti++; 20428 } 20429 dumpState.setDump(DumpState.DUMP_PERMISSIONS 20430 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 20431 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 20432 dumpState.setDump(DumpState.DUMP_PREFERRED); 20433 } else if ("preferred-xml".equals(cmd)) { 20434 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 20435 if (opti < args.length && "--full".equals(args[opti])) { 20436 fullPreferred = true; 20437 opti++; 20438 } 20439 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 20440 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 20441 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 20442 dumpState.setDump(DumpState.DUMP_PACKAGES); 20443 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 20444 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 20445 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 20446 dumpState.setDump(DumpState.DUMP_PROVIDERS); 20447 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 20448 dumpState.setDump(DumpState.DUMP_MESSAGES); 20449 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 20450 dumpState.setDump(DumpState.DUMP_VERIFIERS); 20451 } else if ("i".equals(cmd) || "ifv".equals(cmd) 20452 || "intent-filter-verifiers".equals(cmd)) { 20453 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 20454 } else if ("version".equals(cmd)) { 20455 dumpState.setDump(DumpState.DUMP_VERSION); 20456 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 20457 dumpState.setDump(DumpState.DUMP_KEYSETS); 20458 } else if ("installs".equals(cmd)) { 20459 dumpState.setDump(DumpState.DUMP_INSTALLS); 20460 } else if ("frozen".equals(cmd)) { 20461 dumpState.setDump(DumpState.DUMP_FROZEN); 20462 } else if ("dexopt".equals(cmd)) { 20463 dumpState.setDump(DumpState.DUMP_DEXOPT); 20464 } else if ("compiler-stats".equals(cmd)) { 20465 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 20466 } else if ("enabled-overlays".equals(cmd)) { 20467 dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS); 20468 } else if ("write".equals(cmd)) { 20469 synchronized (mPackages) { 20470 mSettings.writeLPr(); 20471 pw.println("Settings written."); 20472 return; 20473 } 20474 } 20475 } 20476 20477 if (checkin) { 20478 pw.println("vers,1"); 20479 } 20480 20481 // reader 20482 synchronized (mPackages) { 20483 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 20484 if (!checkin) { 20485 if (dumpState.onTitlePrinted()) 20486 pw.println(); 20487 pw.println("Database versions:"); 20488 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 20489 } 20490 } 20491 20492 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 20493 if (!checkin) { 20494 if (dumpState.onTitlePrinted()) 20495 pw.println(); 20496 pw.println("Verifiers:"); 20497 pw.print(" Required: "); 20498 pw.print(mRequiredVerifierPackage); 20499 pw.print(" (uid="); 20500 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 20501 UserHandle.USER_SYSTEM)); 20502 pw.println(")"); 20503 } else if (mRequiredVerifierPackage != null) { 20504 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 20505 pw.print(","); 20506 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 20507 UserHandle.USER_SYSTEM)); 20508 } 20509 } 20510 20511 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 20512 packageName == null) { 20513 if (mIntentFilterVerifierComponent != null) { 20514 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 20515 if (!checkin) { 20516 if (dumpState.onTitlePrinted()) 20517 pw.println(); 20518 pw.println("Intent Filter Verifier:"); 20519 pw.print(" Using: "); 20520 pw.print(verifierPackageName); 20521 pw.print(" (uid="); 20522 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 20523 UserHandle.USER_SYSTEM)); 20524 pw.println(")"); 20525 } else if (verifierPackageName != null) { 20526 pw.print("ifv,"); pw.print(verifierPackageName); 20527 pw.print(","); 20528 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 20529 UserHandle.USER_SYSTEM)); 20530 } 20531 } else { 20532 pw.println(); 20533 pw.println("No Intent Filter Verifier available!"); 20534 } 20535 } 20536 20537 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 20538 boolean printedHeader = false; 20539 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 20540 while (it.hasNext()) { 20541 String libName = it.next(); 20542 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName); 20543 if (versionedLib == null) { 20544 continue; 20545 } 20546 final int versionCount = versionedLib.size(); 20547 for (int i = 0; i < versionCount; i++) { 20548 SharedLibraryEntry libEntry = versionedLib.valueAt(i); 20549 if (!checkin) { 20550 if (!printedHeader) { 20551 if (dumpState.onTitlePrinted()) 20552 pw.println(); 20553 pw.println("Libraries:"); 20554 printedHeader = true; 20555 } 20556 pw.print(" "); 20557 } else { 20558 pw.print("lib,"); 20559 } 20560 pw.print(libEntry.info.getName()); 20561 if (libEntry.info.isStatic()) { 20562 pw.print(" version=" + libEntry.info.getVersion()); 20563 } 20564 if (!checkin) { 20565 pw.print(" -> "); 20566 } 20567 if (libEntry.path != null) { 20568 pw.print(" (jar) "); 20569 pw.print(libEntry.path); 20570 } else { 20571 pw.print(" (apk) "); 20572 pw.print(libEntry.apk); 20573 } 20574 pw.println(); 20575 } 20576 } 20577 } 20578 20579 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 20580 if (dumpState.onTitlePrinted()) 20581 pw.println(); 20582 if (!checkin) { 20583 pw.println("Features:"); 20584 } 20585 20586 synchronized (mAvailableFeatures) { 20587 for (FeatureInfo feat : mAvailableFeatures.values()) { 20588 if (checkin) { 20589 pw.print("feat,"); 20590 pw.print(feat.name); 20591 pw.print(","); 20592 pw.println(feat.version); 20593 } else { 20594 pw.print(" "); 20595 pw.print(feat.name); 20596 if (feat.version > 0) { 20597 pw.print(" version="); 20598 pw.print(feat.version); 20599 } 20600 pw.println(); 20601 } 20602 } 20603 } 20604 } 20605 20606 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 20607 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 20608 : "Activity Resolver Table:", " ", packageName, 20609 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20610 dumpState.setTitlePrinted(true); 20611 } 20612 } 20613 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 20614 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 20615 : "Receiver Resolver Table:", " ", packageName, 20616 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20617 dumpState.setTitlePrinted(true); 20618 } 20619 } 20620 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 20621 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 20622 : "Service Resolver Table:", " ", packageName, 20623 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20624 dumpState.setTitlePrinted(true); 20625 } 20626 } 20627 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 20628 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 20629 : "Provider Resolver Table:", " ", packageName, 20630 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 20631 dumpState.setTitlePrinted(true); 20632 } 20633 } 20634 20635 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 20636 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 20637 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 20638 int user = mSettings.mPreferredActivities.keyAt(i); 20639 if (pir.dump(pw, 20640 dumpState.getTitlePrinted() 20641 ? "\nPreferred Activities User " + user + ":" 20642 : "Preferred Activities User " + user + ":", " ", 20643 packageName, true, false)) { 20644 dumpState.setTitlePrinted(true); 20645 } 20646 } 20647 } 20648 20649 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 20650 pw.flush(); 20651 FileOutputStream fout = new FileOutputStream(fd); 20652 BufferedOutputStream str = new BufferedOutputStream(fout); 20653 XmlSerializer serializer = new FastXmlSerializer(); 20654 try { 20655 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 20656 serializer.startDocument(null, true); 20657 serializer.setFeature( 20658 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 20659 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 20660 serializer.endDocument(); 20661 serializer.flush(); 20662 } catch (IllegalArgumentException e) { 20663 pw.println("Failed writing: " + e); 20664 } catch (IllegalStateException e) { 20665 pw.println("Failed writing: " + e); 20666 } catch (IOException e) { 20667 pw.println("Failed writing: " + e); 20668 } 20669 } 20670 20671 if (!checkin 20672 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 20673 && packageName == null) { 20674 pw.println(); 20675 int count = mSettings.mPackages.size(); 20676 if (count == 0) { 20677 pw.println("No applications!"); 20678 pw.println(); 20679 } else { 20680 final String prefix = " "; 20681 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 20682 if (allPackageSettings.size() == 0) { 20683 pw.println("No domain preferred apps!"); 20684 pw.println(); 20685 } else { 20686 pw.println("App verification status:"); 20687 pw.println(); 20688 count = 0; 20689 for (PackageSetting ps : allPackageSettings) { 20690 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 20691 if (ivi == null || ivi.getPackageName() == null) continue; 20692 pw.println(prefix + "Package: " + ivi.getPackageName()); 20693 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 20694 pw.println(prefix + "Status: " + ivi.getStatusString()); 20695 pw.println(); 20696 count++; 20697 } 20698 if (count == 0) { 20699 pw.println(prefix + "No app verification established."); 20700 pw.println(); 20701 } 20702 for (int userId : sUserManager.getUserIds()) { 20703 pw.println("App linkages for user " + userId + ":"); 20704 pw.println(); 20705 count = 0; 20706 for (PackageSetting ps : allPackageSettings) { 20707 final long status = ps.getDomainVerificationStatusForUser(userId); 20708 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED 20709 && !DEBUG_DOMAIN_VERIFICATION) { 20710 continue; 20711 } 20712 pw.println(prefix + "Package: " + ps.name); 20713 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 20714 String statusStr = IntentFilterVerificationInfo. 20715 getStatusStringFromValue(status); 20716 pw.println(prefix + "Status: " + statusStr); 20717 pw.println(); 20718 count++; 20719 } 20720 if (count == 0) { 20721 pw.println(prefix + "No configured app linkages."); 20722 pw.println(); 20723 } 20724 } 20725 } 20726 } 20727 } 20728 20729 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 20730 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 20731 if (packageName == null && permissionNames == null) { 20732 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 20733 if (iperm == 0) { 20734 if (dumpState.onTitlePrinted()) 20735 pw.println(); 20736 pw.println("AppOp Permissions:"); 20737 } 20738 pw.print(" AppOp Permission "); 20739 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 20740 pw.println(":"); 20741 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 20742 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 20743 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 20744 } 20745 } 20746 } 20747 } 20748 20749 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 20750 boolean printedSomething = false; 20751 for (PackageParser.Provider p : mProviders.mProviders.values()) { 20752 if (packageName != null && !packageName.equals(p.info.packageName)) { 20753 continue; 20754 } 20755 if (!printedSomething) { 20756 if (dumpState.onTitlePrinted()) 20757 pw.println(); 20758 pw.println("Registered ContentProviders:"); 20759 printedSomething = true; 20760 } 20761 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 20762 pw.print(" "); pw.println(p.toString()); 20763 } 20764 printedSomething = false; 20765 for (Map.Entry<String, PackageParser.Provider> entry : 20766 mProvidersByAuthority.entrySet()) { 20767 PackageParser.Provider p = entry.getValue(); 20768 if (packageName != null && !packageName.equals(p.info.packageName)) { 20769 continue; 20770 } 20771 if (!printedSomething) { 20772 if (dumpState.onTitlePrinted()) 20773 pw.println(); 20774 pw.println("ContentProvider Authorities:"); 20775 printedSomething = true; 20776 } 20777 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 20778 pw.print(" "); pw.println(p.toString()); 20779 if (p.info != null && p.info.applicationInfo != null) { 20780 final String appInfo = p.info.applicationInfo.toString(); 20781 pw.print(" applicationInfo="); pw.println(appInfo); 20782 } 20783 } 20784 } 20785 20786 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 20787 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 20788 } 20789 20790 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 20791 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 20792 } 20793 20794 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 20795 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 20796 } 20797 20798 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 20799 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 20800 } 20801 20802 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 20803 // XXX should handle packageName != null by dumping only install data that 20804 // the given package is involved with. 20805 if (dumpState.onTitlePrinted()) pw.println(); 20806 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 20807 } 20808 20809 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 20810 // XXX should handle packageName != null by dumping only install data that 20811 // the given package is involved with. 20812 if (dumpState.onTitlePrinted()) pw.println(); 20813 20814 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20815 ipw.println(); 20816 ipw.println("Frozen packages:"); 20817 ipw.increaseIndent(); 20818 if (mFrozenPackages.size() == 0) { 20819 ipw.println("(none)"); 20820 } else { 20821 for (int i = 0; i < mFrozenPackages.size(); i++) { 20822 ipw.println(mFrozenPackages.valueAt(i)); 20823 } 20824 } 20825 ipw.decreaseIndent(); 20826 } 20827 20828 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 20829 if (dumpState.onTitlePrinted()) pw.println(); 20830 dumpDexoptStateLPr(pw, packageName); 20831 } 20832 20833 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 20834 if (dumpState.onTitlePrinted()) pw.println(); 20835 dumpCompilerStatsLPr(pw, packageName); 20836 } 20837 20838 if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) { 20839 if (dumpState.onTitlePrinted()) pw.println(); 20840 dumpEnabledOverlaysLPr(pw); 20841 } 20842 20843 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 20844 if (dumpState.onTitlePrinted()) pw.println(); 20845 mSettings.dumpReadMessagesLPr(pw, dumpState); 20846 20847 pw.println(); 20848 pw.println("Package warning messages:"); 20849 BufferedReader in = null; 20850 String line = null; 20851 try { 20852 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20853 while ((line = in.readLine()) != null) { 20854 if (line.contains("ignored: updated version")) continue; 20855 pw.println(line); 20856 } 20857 } catch (IOException ignored) { 20858 } finally { 20859 IoUtils.closeQuietly(in); 20860 } 20861 } 20862 20863 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 20864 BufferedReader in = null; 20865 String line = null; 20866 try { 20867 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20868 while ((line = in.readLine()) != null) { 20869 if (line.contains("ignored: updated version")) continue; 20870 pw.print("msg,"); 20871 pw.println(line); 20872 } 20873 } catch (IOException ignored) { 20874 } finally { 20875 IoUtils.closeQuietly(in); 20876 } 20877 } 20878 } 20879 } 20880 20881 private void dumpProto(FileDescriptor fd) { 20882 final ProtoOutputStream proto = new ProtoOutputStream(fd); 20883 20884 synchronized (mPackages) { 20885 final long requiredVerifierPackageToken = 20886 proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE); 20887 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage); 20888 proto.write( 20889 PackageServiceDumpProto.PackageShortProto.UID, 20890 getPackageUid( 20891 mRequiredVerifierPackage, 20892 MATCH_DEBUG_TRIAGED_MISSING, 20893 UserHandle.USER_SYSTEM)); 20894 proto.end(requiredVerifierPackageToken); 20895 20896 if (mIntentFilterVerifierComponent != null) { 20897 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 20898 final long verifierPackageToken = 20899 proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE); 20900 proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName); 20901 proto.write( 20902 PackageServiceDumpProto.PackageShortProto.UID, 20903 getPackageUid( 20904 verifierPackageName, 20905 MATCH_DEBUG_TRIAGED_MISSING, 20906 UserHandle.USER_SYSTEM)); 20907 proto.end(verifierPackageToken); 20908 } 20909 20910 dumpSharedLibrariesProto(proto); 20911 dumpFeaturesProto(proto); 20912 mSettings.dumpPackagesProto(proto); 20913 mSettings.dumpSharedUsersProto(proto); 20914 dumpMessagesProto(proto); 20915 } 20916 proto.flush(); 20917 } 20918 20919 private void dumpMessagesProto(ProtoOutputStream proto) { 20920 BufferedReader in = null; 20921 String line = null; 20922 try { 20923 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 20924 while ((line = in.readLine()) != null) { 20925 if (line.contains("ignored: updated version")) continue; 20926 proto.write(PackageServiceDumpProto.MESSAGES, line); 20927 } 20928 } catch (IOException ignored) { 20929 } finally { 20930 IoUtils.closeQuietly(in); 20931 } 20932 } 20933 20934 private void dumpFeaturesProto(ProtoOutputStream proto) { 20935 synchronized (mAvailableFeatures) { 20936 final int count = mAvailableFeatures.size(); 20937 for (int i = 0; i < count; i++) { 20938 final FeatureInfo feat = mAvailableFeatures.valueAt(i); 20939 final long featureToken = proto.start(PackageServiceDumpProto.FEATURES); 20940 proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name); 20941 proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version); 20942 proto.end(featureToken); 20943 } 20944 } 20945 } 20946 20947 private void dumpSharedLibrariesProto(ProtoOutputStream proto) { 20948 final int count = mSharedLibraries.size(); 20949 for (int i = 0; i < count; i++) { 20950 final String libName = mSharedLibraries.keyAt(i); 20951 SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName); 20952 if (versionedLib == null) { 20953 continue; 20954 } 20955 final int versionCount = versionedLib.size(); 20956 for (int j = 0; j < versionCount; j++) { 20957 final SharedLibraryEntry libEntry = versionedLib.valueAt(j); 20958 final long sharedLibraryToken = 20959 proto.start(PackageServiceDumpProto.SHARED_LIBRARIES); 20960 proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName()); 20961 final boolean isJar = (libEntry.path != null); 20962 proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar); 20963 if (isJar) { 20964 proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path); 20965 } else { 20966 proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk); 20967 } 20968 proto.end(sharedLibraryToken); 20969 } 20970 } 20971 } 20972 20973 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 20974 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 20975 ipw.println(); 20976 ipw.println("Dexopt state:"); 20977 ipw.increaseIndent(); 20978 Collection<PackageParser.Package> packages = null; 20979 if (packageName != null) { 20980 PackageParser.Package targetPackage = mPackages.get(packageName); 20981 if (targetPackage != null) { 20982 packages = Collections.singletonList(targetPackage); 20983 } else { 20984 ipw.println("Unable to find package: " + packageName); 20985 return; 20986 } 20987 } else { 20988 packages = mPackages.values(); 20989 } 20990 20991 for (PackageParser.Package pkg : packages) { 20992 ipw.println("[" + pkg.packageName + "]"); 20993 ipw.increaseIndent(); 20994 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 20995 ipw.decreaseIndent(); 20996 } 20997 } 20998 20999 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 21000 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 21001 ipw.println(); 21002 ipw.println("Compiler stats:"); 21003 ipw.increaseIndent(); 21004 Collection<PackageParser.Package> packages = null; 21005 if (packageName != null) { 21006 PackageParser.Package targetPackage = mPackages.get(packageName); 21007 if (targetPackage != null) { 21008 packages = Collections.singletonList(targetPackage); 21009 } else { 21010 ipw.println("Unable to find package: " + packageName); 21011 return; 21012 } 21013 } else { 21014 packages = mPackages.values(); 21015 } 21016 21017 for (PackageParser.Package pkg : packages) { 21018 ipw.println("[" + pkg.packageName + "]"); 21019 ipw.increaseIndent(); 21020 21021 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 21022 if (stats == null) { 21023 ipw.println("(No recorded stats)"); 21024 } else { 21025 stats.dump(ipw); 21026 } 21027 ipw.decreaseIndent(); 21028 } 21029 } 21030 21031 private void dumpEnabledOverlaysLPr(PrintWriter pw) { 21032 pw.println("Enabled overlay paths:"); 21033 final int N = mEnabledOverlayPaths.size(); 21034 for (int i = 0; i < N; i++) { 21035 final int userId = mEnabledOverlayPaths.keyAt(i); 21036 pw.println(String.format(" User %d:", userId)); 21037 final ArrayMap<String, ArrayList<String>> userSpecificOverlays = 21038 mEnabledOverlayPaths.valueAt(i); 21039 final int M = userSpecificOverlays.size(); 21040 for (int j = 0; j < M; j++) { 21041 final String targetPackageName = userSpecificOverlays.keyAt(j); 21042 final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j); 21043 pw.println(String.format(" %s: %s", targetPackageName, overlayPackagePaths)); 21044 } 21045 } 21046 } 21047 21048 private String dumpDomainString(String packageName) { 21049 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 21050 .getList(); 21051 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 21052 21053 ArraySet<String> result = new ArraySet<>(); 21054 if (iviList.size() > 0) { 21055 for (IntentFilterVerificationInfo ivi : iviList) { 21056 for (String host : ivi.getDomains()) { 21057 result.add(host); 21058 } 21059 } 21060 } 21061 if (filters != null && filters.size() > 0) { 21062 for (IntentFilter filter : filters) { 21063 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 21064 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 21065 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 21066 result.addAll(filter.getHostsList()); 21067 } 21068 } 21069 } 21070 21071 StringBuilder sb = new StringBuilder(result.size() * 16); 21072 for (String domain : result) { 21073 if (sb.length() > 0) sb.append(" "); 21074 sb.append(domain); 21075 } 21076 return sb.toString(); 21077 } 21078 21079 // ------- apps on sdcard specific code ------- 21080 static final boolean DEBUG_SD_INSTALL = false; 21081 21082 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 21083 21084 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 21085 21086 private boolean mMediaMounted = false; 21087 21088 static String getEncryptKey() { 21089 try { 21090 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 21091 SD_ENCRYPTION_KEYSTORE_NAME); 21092 if (sdEncKey == null) { 21093 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 21094 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 21095 if (sdEncKey == null) { 21096 Slog.e(TAG, "Failed to create encryption keys"); 21097 return null; 21098 } 21099 } 21100 return sdEncKey; 21101 } catch (NoSuchAlgorithmException nsae) { 21102 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 21103 return null; 21104 } catch (IOException ioe) { 21105 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 21106 return null; 21107 } 21108 } 21109 21110 /* 21111 * Update media status on PackageManager. 21112 */ 21113 @Override 21114 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 21115 int callingUid = Binder.getCallingUid(); 21116 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 21117 throw new SecurityException("Media status can only be updated by the system"); 21118 } 21119 // reader; this apparently protects mMediaMounted, but should probably 21120 // be a different lock in that case. 21121 synchronized (mPackages) { 21122 Log.i(TAG, "Updating external media status from " 21123 + (mMediaMounted ? "mounted" : "unmounted") + " to " 21124 + (mediaStatus ? "mounted" : "unmounted")); 21125 if (DEBUG_SD_INSTALL) 21126 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 21127 + ", mMediaMounted=" + mMediaMounted); 21128 if (mediaStatus == mMediaMounted) { 21129 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 21130 : 0, -1); 21131 mHandler.sendMessage(msg); 21132 return; 21133 } 21134 mMediaMounted = mediaStatus; 21135 } 21136 // Queue up an async operation since the package installation may take a 21137 // little while. 21138 mHandler.post(new Runnable() { 21139 public void run() { 21140 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 21141 } 21142 }); 21143 } 21144 21145 /** 21146 * Called by StorageManagerService when the initial ASECs to scan are available. 21147 * Should block until all the ASEC containers are finished being scanned. 21148 */ 21149 public void scanAvailableAsecs() { 21150 updateExternalMediaStatusInner(true, false, false); 21151 } 21152 21153 /* 21154 * Collect information of applications on external media, map them against 21155 * existing containers and update information based on current mount status. 21156 * Please note that we always have to report status if reportStatus has been 21157 * set to true especially when unloading packages. 21158 */ 21159 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 21160 boolean externalStorage) { 21161 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 21162 int[] uidArr = EmptyArray.INT; 21163 21164 final String[] list = PackageHelper.getSecureContainerList(); 21165 if (ArrayUtils.isEmpty(list)) { 21166 Log.i(TAG, "No secure containers found"); 21167 } else { 21168 // Process list of secure containers and categorize them 21169 // as active or stale based on their package internal state. 21170 21171 // reader 21172 synchronized (mPackages) { 21173 for (String cid : list) { 21174 // Leave stages untouched for now; installer service owns them 21175 if (PackageInstallerService.isStageName(cid)) continue; 21176 21177 if (DEBUG_SD_INSTALL) 21178 Log.i(TAG, "Processing container " + cid); 21179 String pkgName = getAsecPackageName(cid); 21180 if (pkgName == null) { 21181 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 21182 continue; 21183 } 21184 if (DEBUG_SD_INSTALL) 21185 Log.i(TAG, "Looking for pkg : " + pkgName); 21186 21187 final PackageSetting ps = mSettings.mPackages.get(pkgName); 21188 if (ps == null) { 21189 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 21190 continue; 21191 } 21192 21193 /* 21194 * Skip packages that are not external if we're unmounting 21195 * external storage. 21196 */ 21197 if (externalStorage && !isMounted && !isExternal(ps)) { 21198 continue; 21199 } 21200 21201 final AsecInstallArgs args = new AsecInstallArgs(cid, 21202 getAppDexInstructionSets(ps), ps.isForwardLocked()); 21203 // The package status is changed only if the code path 21204 // matches between settings and the container id. 21205 if (ps.codePathString != null 21206 && ps.codePathString.startsWith(args.getCodePath())) { 21207 if (DEBUG_SD_INSTALL) { 21208 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 21209 + " at code path: " + ps.codePathString); 21210 } 21211 21212 // We do have a valid package installed on sdcard 21213 processCids.put(args, ps.codePathString); 21214 final int uid = ps.appId; 21215 if (uid != -1) { 21216 uidArr = ArrayUtils.appendInt(uidArr, uid); 21217 } 21218 } else { 21219 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 21220 + ps.codePathString); 21221 } 21222 } 21223 } 21224 21225 Arrays.sort(uidArr); 21226 } 21227 21228 // Process packages with valid entries. 21229 if (isMounted) { 21230 if (DEBUG_SD_INSTALL) 21231 Log.i(TAG, "Loading packages"); 21232 loadMediaPackages(processCids, uidArr, externalStorage); 21233 startCleaningPackages(); 21234 mInstallerService.onSecureContainersAvailable(); 21235 } else { 21236 if (DEBUG_SD_INSTALL) 21237 Log.i(TAG, "Unloading packages"); 21238 unloadMediaPackages(processCids, uidArr, reportStatus); 21239 } 21240 } 21241 21242 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21243 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 21244 final int size = infos.size(); 21245 final String[] packageNames = new String[size]; 21246 final int[] packageUids = new int[size]; 21247 for (int i = 0; i < size; i++) { 21248 final ApplicationInfo info = infos.get(i); 21249 packageNames[i] = info.packageName; 21250 packageUids[i] = info.uid; 21251 } 21252 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 21253 finishedReceiver); 21254 } 21255 21256 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21257 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 21258 sendResourcesChangedBroadcast(mediaStatus, replacing, 21259 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 21260 } 21261 21262 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 21263 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 21264 int size = pkgList.length; 21265 if (size > 0) { 21266 // Send broadcasts here 21267 Bundle extras = new Bundle(); 21268 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 21269 if (uidArr != null) { 21270 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 21271 } 21272 if (replacing) { 21273 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 21274 } 21275 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 21276 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 21277 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 21278 } 21279 } 21280 21281 /* 21282 * Look at potentially valid container ids from processCids If package 21283 * information doesn't match the one on record or package scanning fails, 21284 * the cid is added to list of removeCids. We currently don't delete stale 21285 * containers. 21286 */ 21287 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 21288 boolean externalStorage) { 21289 ArrayList<String> pkgList = new ArrayList<String>(); 21290 Set<AsecInstallArgs> keys = processCids.keySet(); 21291 21292 for (AsecInstallArgs args : keys) { 21293 String codePath = processCids.get(args); 21294 if (DEBUG_SD_INSTALL) 21295 Log.i(TAG, "Loading container : " + args.cid); 21296 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 21297 try { 21298 // Make sure there are no container errors first. 21299 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 21300 Slog.e(TAG, "Failed to mount cid : " + args.cid 21301 + " when installing from sdcard"); 21302 continue; 21303 } 21304 // Check code path here. 21305 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 21306 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 21307 + " does not match one in settings " + codePath); 21308 continue; 21309 } 21310 // Parse package 21311 int parseFlags = mDefParseFlags; 21312 if (args.isExternalAsec()) { 21313 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 21314 } 21315 if (args.isFwdLocked()) { 21316 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 21317 } 21318 21319 synchronized (mInstallLock) { 21320 PackageParser.Package pkg = null; 21321 try { 21322 // Sadly we don't know the package name yet to freeze it 21323 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 21324 SCAN_IGNORE_FROZEN, 0, null); 21325 } catch (PackageManagerException e) { 21326 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 21327 } 21328 // Scan the package 21329 if (pkg != null) { 21330 /* 21331 * TODO why is the lock being held? doPostInstall is 21332 * called in other places without the lock. This needs 21333 * to be straightened out. 21334 */ 21335 // writer 21336 synchronized (mPackages) { 21337 retCode = PackageManager.INSTALL_SUCCEEDED; 21338 pkgList.add(pkg.packageName); 21339 // Post process args 21340 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 21341 pkg.applicationInfo.uid); 21342 } 21343 } else { 21344 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 21345 } 21346 } 21347 21348 } finally { 21349 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 21350 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 21351 } 21352 } 21353 } 21354 // writer 21355 synchronized (mPackages) { 21356 // If the platform SDK has changed since the last time we booted, 21357 // we need to re-grant app permission to catch any new ones that 21358 // appear. This is really a hack, and means that apps can in some 21359 // cases get permissions that the user didn't initially explicitly 21360 // allow... it would be nice to have some better way to handle 21361 // this situation. 21362 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 21363 : mSettings.getInternalVersion(); 21364 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 21365 : StorageManager.UUID_PRIVATE_INTERNAL; 21366 21367 int updateFlags = UPDATE_PERMISSIONS_ALL; 21368 if (ver.sdkVersion != mSdkVersion) { 21369 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 21370 + mSdkVersion + "; regranting permissions for external"); 21371 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 21372 } 21373 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 21374 21375 // Yay, everything is now upgraded 21376 ver.forceCurrent(); 21377 21378 // can downgrade to reader 21379 // Persist settings 21380 mSettings.writeLPr(); 21381 } 21382 // Send a broadcast to let everyone know we are done processing 21383 if (pkgList.size() > 0) { 21384 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 21385 } 21386 } 21387 21388 /* 21389 * Utility method to unload a list of specified containers 21390 */ 21391 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 21392 // Just unmount all valid containers. 21393 for (AsecInstallArgs arg : cidArgs) { 21394 synchronized (mInstallLock) { 21395 arg.doPostDeleteLI(false); 21396 } 21397 } 21398 } 21399 21400 /* 21401 * Unload packages mounted on external media. This involves deleting package 21402 * data from internal structures, sending broadcasts about disabled packages, 21403 * gc'ing to free up references, unmounting all secure containers 21404 * corresponding to packages on external media, and posting a 21405 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 21406 * that we always have to post this message if status has been requested no 21407 * matter what. 21408 */ 21409 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 21410 final boolean reportStatus) { 21411 if (DEBUG_SD_INSTALL) 21412 Log.i(TAG, "unloading media packages"); 21413 ArrayList<String> pkgList = new ArrayList<String>(); 21414 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 21415 final Set<AsecInstallArgs> keys = processCids.keySet(); 21416 for (AsecInstallArgs args : keys) { 21417 String pkgName = args.getPackageName(); 21418 if (DEBUG_SD_INSTALL) 21419 Log.i(TAG, "Trying to unload pkg : " + pkgName); 21420 // Delete package internally 21421 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 21422 synchronized (mInstallLock) { 21423 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 21424 final boolean res; 21425 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 21426 "unloadMediaPackages")) { 21427 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 21428 null); 21429 } 21430 if (res) { 21431 pkgList.add(pkgName); 21432 } else { 21433 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 21434 failedList.add(args); 21435 } 21436 } 21437 } 21438 21439 // reader 21440 synchronized (mPackages) { 21441 // We didn't update the settings after removing each package; 21442 // write them now for all packages. 21443 mSettings.writeLPr(); 21444 } 21445 21446 // We have to absolutely send UPDATED_MEDIA_STATUS only 21447 // after confirming that all the receivers processed the ordered 21448 // broadcast when packages get disabled, force a gc to clean things up. 21449 // and unload all the containers. 21450 if (pkgList.size() > 0) { 21451 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 21452 new IIntentReceiver.Stub() { 21453 public void performReceive(Intent intent, int resultCode, String data, 21454 Bundle extras, boolean ordered, boolean sticky, 21455 int sendingUser) throws RemoteException { 21456 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 21457 reportStatus ? 1 : 0, 1, keys); 21458 mHandler.sendMessage(msg); 21459 } 21460 }); 21461 } else { 21462 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 21463 keys); 21464 mHandler.sendMessage(msg); 21465 } 21466 } 21467 21468 private void loadPrivatePackages(final VolumeInfo vol) { 21469 mHandler.post(new Runnable() { 21470 @Override 21471 public void run() { 21472 loadPrivatePackagesInner(vol); 21473 } 21474 }); 21475 } 21476 21477 private void loadPrivatePackagesInner(VolumeInfo vol) { 21478 final String volumeUuid = vol.fsUuid; 21479 if (TextUtils.isEmpty(volumeUuid)) { 21480 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 21481 return; 21482 } 21483 21484 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 21485 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 21486 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 21487 21488 final VersionInfo ver; 21489 final List<PackageSetting> packages; 21490 synchronized (mPackages) { 21491 ver = mSettings.findOrCreateVersion(volumeUuid); 21492 packages = mSettings.getVolumePackagesLPr(volumeUuid); 21493 } 21494 21495 for (PackageSetting ps : packages) { 21496 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 21497 synchronized (mInstallLock) { 21498 final PackageParser.Package pkg; 21499 try { 21500 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 21501 loaded.add(pkg.applicationInfo); 21502 21503 } catch (PackageManagerException e) { 21504 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 21505 } 21506 21507 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 21508 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 21509 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 21510 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 21511 } 21512 } 21513 } 21514 21515 // Reconcile app data for all started/unlocked users 21516 final StorageManager sm = mContext.getSystemService(StorageManager.class); 21517 final UserManager um = mContext.getSystemService(UserManager.class); 21518 UserManagerInternal umInternal = getUserManagerInternal(); 21519 for (UserInfo user : um.getUsers()) { 21520 final int flags; 21521 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 21522 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 21523 } else if (umInternal.isUserRunning(user.id)) { 21524 flags = StorageManager.FLAG_STORAGE_DE; 21525 } else { 21526 continue; 21527 } 21528 21529 try { 21530 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 21531 synchronized (mInstallLock) { 21532 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */); 21533 } 21534 } catch (IllegalStateException e) { 21535 // Device was probably ejected, and we'll process that event momentarily 21536 Slog.w(TAG, "Failed to prepare storage: " + e); 21537 } 21538 } 21539 21540 synchronized (mPackages) { 21541 int updateFlags = UPDATE_PERMISSIONS_ALL; 21542 if (ver.sdkVersion != mSdkVersion) { 21543 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 21544 + mSdkVersion + "; regranting permissions for " + volumeUuid); 21545 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 21546 } 21547 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 21548 21549 // Yay, everything is now upgraded 21550 ver.forceCurrent(); 21551 21552 mSettings.writeLPr(); 21553 } 21554 21555 for (PackageFreezer freezer : freezers) { 21556 freezer.close(); 21557 } 21558 21559 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 21560 sendResourcesChangedBroadcast(true, false, loaded, null); 21561 } 21562 21563 private void unloadPrivatePackages(final VolumeInfo vol) { 21564 mHandler.post(new Runnable() { 21565 @Override 21566 public void run() { 21567 unloadPrivatePackagesInner(vol); 21568 } 21569 }); 21570 } 21571 21572 private void unloadPrivatePackagesInner(VolumeInfo vol) { 21573 final String volumeUuid = vol.fsUuid; 21574 if (TextUtils.isEmpty(volumeUuid)) { 21575 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 21576 return; 21577 } 21578 21579 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 21580 synchronized (mInstallLock) { 21581 synchronized (mPackages) { 21582 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 21583 for (PackageSetting ps : packages) { 21584 if (ps.pkg == null) continue; 21585 21586 final ApplicationInfo info = ps.pkg.applicationInfo; 21587 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 21588 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 21589 21590 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 21591 "unloadPrivatePackagesInner")) { 21592 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 21593 false, null)) { 21594 unloaded.add(info); 21595 } else { 21596 Slog.w(TAG, "Failed to unload " + ps.codePath); 21597 } 21598 } 21599 21600 // Try very hard to release any references to this package 21601 // so we don't risk the system server being killed due to 21602 // open FDs 21603 AttributeCache.instance().removePackage(ps.name); 21604 } 21605 21606 mSettings.writeLPr(); 21607 } 21608 } 21609 21610 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 21611 sendResourcesChangedBroadcast(false, false, unloaded, null); 21612 21613 // Try very hard to release any references to this path so we don't risk 21614 // the system server being killed due to open FDs 21615 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 21616 21617 for (int i = 0; i < 3; i++) { 21618 System.gc(); 21619 System.runFinalization(); 21620 } 21621 } 21622 21623 private void assertPackageKnown(String volumeUuid, String packageName) 21624 throws PackageManagerException { 21625 synchronized (mPackages) { 21626 // Normalize package name to handle renamed packages 21627 packageName = normalizePackageNameLPr(packageName); 21628 21629 final PackageSetting ps = mSettings.mPackages.get(packageName); 21630 if (ps == null) { 21631 throw new PackageManagerException("Package " + packageName + " is unknown"); 21632 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 21633 throw new PackageManagerException( 21634 "Package " + packageName + " found on unknown volume " + volumeUuid 21635 + "; expected volume " + ps.volumeUuid); 21636 } 21637 } 21638 } 21639 21640 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 21641 throws PackageManagerException { 21642 synchronized (mPackages) { 21643 // Normalize package name to handle renamed packages 21644 packageName = normalizePackageNameLPr(packageName); 21645 21646 final PackageSetting ps = mSettings.mPackages.get(packageName); 21647 if (ps == null) { 21648 throw new PackageManagerException("Package " + packageName + " is unknown"); 21649 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 21650 throw new PackageManagerException( 21651 "Package " + packageName + " found on unknown volume " + volumeUuid 21652 + "; expected volume " + ps.volumeUuid); 21653 } else if (!ps.getInstalled(userId)) { 21654 throw new PackageManagerException( 21655 "Package " + packageName + " not installed for user " + userId); 21656 } 21657 } 21658 } 21659 21660 private List<String> collectAbsoluteCodePaths() { 21661 synchronized (mPackages) { 21662 List<String> codePaths = new ArrayList<>(); 21663 final int packageCount = mSettings.mPackages.size(); 21664 for (int i = 0; i < packageCount; i++) { 21665 final PackageSetting ps = mSettings.mPackages.valueAt(i); 21666 codePaths.add(ps.codePath.getAbsolutePath()); 21667 } 21668 return codePaths; 21669 } 21670 } 21671 21672 /** 21673 * Examine all apps present on given mounted volume, and destroy apps that 21674 * aren't expected, either due to uninstallation or reinstallation on 21675 * another volume. 21676 */ 21677 private void reconcileApps(String volumeUuid) { 21678 List<String> absoluteCodePaths = collectAbsoluteCodePaths(); 21679 List<File> filesToDelete = null; 21680 21681 final File[] files = FileUtils.listFilesOrEmpty( 21682 Environment.getDataAppDirectory(volumeUuid)); 21683 for (File file : files) { 21684 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 21685 && !PackageInstallerService.isStageName(file.getName()); 21686 if (!isPackage) { 21687 // Ignore entries which are not packages 21688 continue; 21689 } 21690 21691 String absolutePath = file.getAbsolutePath(); 21692 21693 boolean pathValid = false; 21694 final int absoluteCodePathCount = absoluteCodePaths.size(); 21695 for (int i = 0; i < absoluteCodePathCount; i++) { 21696 String absoluteCodePath = absoluteCodePaths.get(i); 21697 if (absolutePath.startsWith(absoluteCodePath)) { 21698 pathValid = true; 21699 break; 21700 } 21701 } 21702 21703 if (!pathValid) { 21704 if (filesToDelete == null) { 21705 filesToDelete = new ArrayList<>(); 21706 } 21707 filesToDelete.add(file); 21708 } 21709 } 21710 21711 if (filesToDelete != null) { 21712 final int fileToDeleteCount = filesToDelete.size(); 21713 for (int i = 0; i < fileToDeleteCount; i++) { 21714 File fileToDelete = filesToDelete.get(i); 21715 logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete); 21716 synchronized (mInstallLock) { 21717 removeCodePathLI(fileToDelete); 21718 } 21719 } 21720 } 21721 } 21722 21723 /** 21724 * Reconcile all app data for the given user. 21725 * <p> 21726 * Verifies that directories exist and that ownership and labeling is 21727 * correct for all installed apps on all mounted volumes. 21728 */ 21729 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) { 21730 final StorageManager storage = mContext.getSystemService(StorageManager.class); 21731 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 21732 final String volumeUuid = vol.getFsUuid(); 21733 synchronized (mInstallLock) { 21734 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData); 21735 } 21736 } 21737 } 21738 21739 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags, 21740 boolean migrateAppData) { 21741 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */); 21742 } 21743 21744 /** 21745 * Reconcile all app data on given mounted volume. 21746 * <p> 21747 * Destroys app data that isn't expected, either due to uninstallation or 21748 * reinstallation on another volume. 21749 * <p> 21750 * Verifies that directories exist and that ownership and labeling is 21751 * correct for all installed apps. 21752 * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true) 21753 */ 21754 private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags, 21755 boolean migrateAppData, boolean onlyCoreApps) { 21756 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 21757 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData); 21758 List<String> result = onlyCoreApps ? new ArrayList<>() : null; 21759 21760 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 21761 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 21762 21763 // First look for stale data that doesn't belong, and check if things 21764 // have changed since we did our last restorecon 21765 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 21766 if (StorageManager.isFileEncryptedNativeOrEmulated() 21767 && !StorageManager.isUserKeyUnlocked(userId)) { 21768 throw new RuntimeException( 21769 "Yikes, someone asked us to reconcile CE storage while " + userId 21770 + " was still locked; this would have caused massive data loss!"); 21771 } 21772 21773 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 21774 for (File file : files) { 21775 final String packageName = file.getName(); 21776 try { 21777 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 21778 } catch (PackageManagerException e) { 21779 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 21780 try { 21781 mInstaller.destroyAppData(volumeUuid, packageName, userId, 21782 StorageManager.FLAG_STORAGE_CE, 0); 21783 } catch (InstallerException e2) { 21784 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 21785 } 21786 } 21787 } 21788 } 21789 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 21790 final File[] files = FileUtils.listFilesOrEmpty(deDir); 21791 for (File file : files) { 21792 final String packageName = file.getName(); 21793 try { 21794 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 21795 } catch (PackageManagerException e) { 21796 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 21797 try { 21798 mInstaller.destroyAppData(volumeUuid, packageName, userId, 21799 StorageManager.FLAG_STORAGE_DE, 0); 21800 } catch (InstallerException e2) { 21801 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 21802 } 21803 } 21804 } 21805 } 21806 21807 // Ensure that data directories are ready to roll for all packages 21808 // installed for this volume and user 21809 final List<PackageSetting> packages; 21810 synchronized (mPackages) { 21811 packages = mSettings.getVolumePackagesLPr(volumeUuid); 21812 } 21813 int preparedCount = 0; 21814 for (PackageSetting ps : packages) { 21815 final String packageName = ps.name; 21816 if (ps.pkg == null) { 21817 Slog.w(TAG, "Odd, missing scanned package " + packageName); 21818 // TODO: might be due to legacy ASEC apps; we should circle back 21819 // and reconcile again once they're scanned 21820 continue; 21821 } 21822 // Skip non-core apps if requested 21823 if (onlyCoreApps && !ps.pkg.coreApp) { 21824 result.add(packageName); 21825 continue; 21826 } 21827 21828 if (ps.getInstalled(userId)) { 21829 prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData); 21830 preparedCount++; 21831 } 21832 } 21833 21834 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); 21835 return result; 21836 } 21837 21838 /** 21839 * Prepare app data for the given app just after it was installed or 21840 * upgraded. This method carefully only touches users that it's installed 21841 * for, and it forces a restorecon to handle any seinfo changes. 21842 * <p> 21843 * Verifies that directories exist and that ownership and labeling is 21844 * correct for all installed apps. If there is an ownership mismatch, it 21845 * will try recovering system apps by wiping data; third-party app data is 21846 * left intact. 21847 * <p> 21848 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 21849 */ 21850 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 21851 final PackageSetting ps; 21852 synchronized (mPackages) { 21853 ps = mSettings.mPackages.get(pkg.packageName); 21854 mSettings.writeKernelMappingLPr(ps); 21855 } 21856 21857 final UserManager um = mContext.getSystemService(UserManager.class); 21858 UserManagerInternal umInternal = getUserManagerInternal(); 21859 for (UserInfo user : um.getUsers()) { 21860 final int flags; 21861 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 21862 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 21863 } else if (umInternal.isUserRunning(user.id)) { 21864 flags = StorageManager.FLAG_STORAGE_DE; 21865 } else { 21866 continue; 21867 } 21868 21869 if (ps.getInstalled(user.id)) { 21870 // TODO: when user data is locked, mark that we're still dirty 21871 prepareAppDataLIF(pkg, user.id, flags); 21872 } 21873 } 21874 } 21875 21876 /** 21877 * Prepare app data for the given app. 21878 * <p> 21879 * Verifies that directories exist and that ownership and labeling is 21880 * correct for all installed apps. If there is an ownership mismatch, this 21881 * will try recovering system apps by wiping data; third-party app data is 21882 * left intact. 21883 */ 21884 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 21885 if (pkg == null) { 21886 Slog.wtf(TAG, "Package was null!", new Throwable()); 21887 return; 21888 } 21889 prepareAppDataLeafLIF(pkg, userId, flags); 21890 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 21891 for (int i = 0; i < childCount; i++) { 21892 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 21893 } 21894 } 21895 21896 private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags, 21897 boolean maybeMigrateAppData) { 21898 prepareAppDataLIF(pkg, userId, flags); 21899 21900 if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) { 21901 // We may have just shuffled around app data directories, so 21902 // prepare them one more time 21903 prepareAppDataLIF(pkg, userId, flags); 21904 } 21905 } 21906 21907 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 21908 if (DEBUG_APP_DATA) { 21909 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 21910 + Integer.toHexString(flags)); 21911 } 21912 21913 final String volumeUuid = pkg.volumeUuid; 21914 final String packageName = pkg.packageName; 21915 final ApplicationInfo app = pkg.applicationInfo; 21916 final int appId = UserHandle.getAppId(app.uid); 21917 21918 Preconditions.checkNotNull(app.seInfo); 21919 21920 long ceDataInode = -1; 21921 try { 21922 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 21923 appId, app.seInfo, app.targetSdkVersion); 21924 } catch (InstallerException e) { 21925 if (app.isSystemApp()) { 21926 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 21927 + ", but trying to recover: " + e); 21928 destroyAppDataLeafLIF(pkg, userId, flags); 21929 try { 21930 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 21931 appId, app.seInfo, app.targetSdkVersion); 21932 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 21933 } catch (InstallerException e2) { 21934 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 21935 } 21936 } else { 21937 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 21938 } 21939 } 21940 21941 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { 21942 // TODO: mark this structure as dirty so we persist it! 21943 synchronized (mPackages) { 21944 final PackageSetting ps = mSettings.mPackages.get(packageName); 21945 if (ps != null) { 21946 ps.setCeDataInode(ceDataInode, userId); 21947 } 21948 } 21949 } 21950 21951 prepareAppDataContentsLeafLIF(pkg, userId, flags); 21952 } 21953 21954 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 21955 if (pkg == null) { 21956 Slog.wtf(TAG, "Package was null!", new Throwable()); 21957 return; 21958 } 21959 prepareAppDataContentsLeafLIF(pkg, userId, flags); 21960 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 21961 for (int i = 0; i < childCount; i++) { 21962 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 21963 } 21964 } 21965 21966 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 21967 final String volumeUuid = pkg.volumeUuid; 21968 final String packageName = pkg.packageName; 21969 final ApplicationInfo app = pkg.applicationInfo; 21970 21971 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 21972 // Create a native library symlink only if we have native libraries 21973 // and if the native libraries are 32 bit libraries. We do not provide 21974 // this symlink for 64 bit libraries. 21975 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 21976 final String nativeLibPath = app.nativeLibraryDir; 21977 try { 21978 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 21979 nativeLibPath, userId); 21980 } catch (InstallerException e) { 21981 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 21982 } 21983 } 21984 } 21985 } 21986 21987 /** 21988 * For system apps on non-FBE devices, this method migrates any existing 21989 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 21990 * requested by the app. 21991 */ 21992 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 21993 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 21994 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 21995 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 21996 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 21997 try { 21998 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 21999 storageTarget); 22000 } catch (InstallerException e) { 22001 logCriticalInfo(Log.WARN, 22002 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 22003 } 22004 return true; 22005 } else { 22006 return false; 22007 } 22008 } 22009 22010 public PackageFreezer freezePackage(String packageName, String killReason) { 22011 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 22012 } 22013 22014 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 22015 return new PackageFreezer(packageName, userId, killReason); 22016 } 22017 22018 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 22019 String killReason) { 22020 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 22021 } 22022 22023 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 22024 String killReason) { 22025 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 22026 return new PackageFreezer(); 22027 } else { 22028 return freezePackage(packageName, userId, killReason); 22029 } 22030 } 22031 22032 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 22033 String killReason) { 22034 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 22035 } 22036 22037 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 22038 String killReason) { 22039 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 22040 return new PackageFreezer(); 22041 } else { 22042 return freezePackage(packageName, userId, killReason); 22043 } 22044 } 22045 22046 /** 22047 * Class that freezes and kills the given package upon creation, and 22048 * unfreezes it upon closing. This is typically used when doing surgery on 22049 * app code/data to prevent the app from running while you're working. 22050 */ 22051 private class PackageFreezer implements AutoCloseable { 22052 private final String mPackageName; 22053 private final PackageFreezer[] mChildren; 22054 22055 private final boolean mWeFroze; 22056 22057 private final AtomicBoolean mClosed = new AtomicBoolean(); 22058 private final CloseGuard mCloseGuard = CloseGuard.get(); 22059 22060 /** 22061 * Create and return a stub freezer that doesn't actually do anything, 22062 * typically used when someone requested 22063 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 22064 * {@link PackageManager#DELETE_DONT_KILL_APP}. 22065 */ 22066 public PackageFreezer() { 22067 mPackageName = null; 22068 mChildren = null; 22069 mWeFroze = false; 22070 mCloseGuard.open("close"); 22071 } 22072 22073 public PackageFreezer(String packageName, int userId, String killReason) { 22074 synchronized (mPackages) { 22075 mPackageName = packageName; 22076 mWeFroze = mFrozenPackages.add(mPackageName); 22077 22078 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 22079 if (ps != null) { 22080 killApplication(ps.name, ps.appId, userId, killReason); 22081 } 22082 22083 final PackageParser.Package p = mPackages.get(packageName); 22084 if (p != null && p.childPackages != null) { 22085 final int N = p.childPackages.size(); 22086 mChildren = new PackageFreezer[N]; 22087 for (int i = 0; i < N; i++) { 22088 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 22089 userId, killReason); 22090 } 22091 } else { 22092 mChildren = null; 22093 } 22094 } 22095 mCloseGuard.open("close"); 22096 } 22097 22098 @Override 22099 protected void finalize() throws Throwable { 22100 try { 22101 mCloseGuard.warnIfOpen(); 22102 close(); 22103 } finally { 22104 super.finalize(); 22105 } 22106 } 22107 22108 @Override 22109 public void close() { 22110 mCloseGuard.close(); 22111 if (mClosed.compareAndSet(false, true)) { 22112 synchronized (mPackages) { 22113 if (mWeFroze) { 22114 mFrozenPackages.remove(mPackageName); 22115 } 22116 22117 if (mChildren != null) { 22118 for (PackageFreezer freezer : mChildren) { 22119 freezer.close(); 22120 } 22121 } 22122 } 22123 } 22124 } 22125 } 22126 22127 /** 22128 * Verify that given package is currently frozen. 22129 */ 22130 private void checkPackageFrozen(String packageName) { 22131 synchronized (mPackages) { 22132 if (!mFrozenPackages.contains(packageName)) { 22133 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 22134 } 22135 } 22136 } 22137 22138 @Override 22139 public int movePackage(final String packageName, final String volumeUuid) { 22140 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 22141 22142 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 22143 final int moveId = mNextMoveId.getAndIncrement(); 22144 mHandler.post(new Runnable() { 22145 @Override 22146 public void run() { 22147 try { 22148 movePackageInternal(packageName, volumeUuid, moveId, user); 22149 } catch (PackageManagerException e) { 22150 Slog.w(TAG, "Failed to move " + packageName, e); 22151 mMoveCallbacks.notifyStatusChanged(moveId, 22152 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 22153 } 22154 } 22155 }); 22156 return moveId; 22157 } 22158 22159 private void movePackageInternal(final String packageName, final String volumeUuid, 22160 final int moveId, UserHandle user) throws PackageManagerException { 22161 final StorageManager storage = mContext.getSystemService(StorageManager.class); 22162 final PackageManager pm = mContext.getPackageManager(); 22163 22164 final boolean currentAsec; 22165 final String currentVolumeUuid; 22166 final File codeFile; 22167 final String installerPackageName; 22168 final String packageAbiOverride; 22169 final int appId; 22170 final String seinfo; 22171 final String label; 22172 final int targetSdkVersion; 22173 final PackageFreezer freezer; 22174 final int[] installedUserIds; 22175 22176 // reader 22177 synchronized (mPackages) { 22178 final PackageParser.Package pkg = mPackages.get(packageName); 22179 final PackageSetting ps = mSettings.mPackages.get(packageName); 22180 if (pkg == null || ps == null) { 22181 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 22182 } 22183 22184 if (pkg.applicationInfo.isSystemApp()) { 22185 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 22186 "Cannot move system application"); 22187 } 22188 22189 final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid); 22190 final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean( 22191 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal); 22192 if (isInternalStorage && !allow3rdPartyOnInternal) { 22193 throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL, 22194 "3rd party apps are not allowed on internal storage"); 22195 } 22196 22197 if (pkg.applicationInfo.isExternalAsec()) { 22198 currentAsec = true; 22199 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 22200 } else if (pkg.applicationInfo.isForwardLocked()) { 22201 currentAsec = true; 22202 currentVolumeUuid = "forward_locked"; 22203 } else { 22204 currentAsec = false; 22205 currentVolumeUuid = ps.volumeUuid; 22206 22207 final File probe = new File(pkg.codePath); 22208 final File probeOat = new File(probe, "oat"); 22209 if (!probe.isDirectory() || !probeOat.isDirectory()) { 22210 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22211 "Move only supported for modern cluster style installs"); 22212 } 22213 } 22214 22215 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 22216 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22217 "Package already moved to " + volumeUuid); 22218 } 22219 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 22220 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 22221 "Device admin cannot be moved"); 22222 } 22223 22224 if (mFrozenPackages.contains(packageName)) { 22225 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 22226 "Failed to move already frozen package"); 22227 } 22228 22229 codeFile = new File(pkg.codePath); 22230 installerPackageName = ps.installerPackageName; 22231 packageAbiOverride = ps.cpuAbiOverrideString; 22232 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 22233 seinfo = pkg.applicationInfo.seInfo; 22234 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 22235 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 22236 freezer = freezePackage(packageName, "movePackageInternal"); 22237 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 22238 } 22239 22240 final Bundle extras = new Bundle(); 22241 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 22242 extras.putString(Intent.EXTRA_TITLE, label); 22243 mMoveCallbacks.notifyCreated(moveId, extras); 22244 22245 int installFlags; 22246 final boolean moveCompleteApp; 22247 final File measurePath; 22248 22249 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 22250 installFlags = INSTALL_INTERNAL; 22251 moveCompleteApp = !currentAsec; 22252 measurePath = Environment.getDataAppDirectory(volumeUuid); 22253 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 22254 installFlags = INSTALL_EXTERNAL; 22255 moveCompleteApp = false; 22256 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 22257 } else { 22258 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 22259 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 22260 || !volume.isMountedWritable()) { 22261 freezer.close(); 22262 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22263 "Move location not mounted private volume"); 22264 } 22265 22266 Preconditions.checkState(!currentAsec); 22267 22268 installFlags = INSTALL_INTERNAL; 22269 moveCompleteApp = true; 22270 measurePath = Environment.getDataAppDirectory(volumeUuid); 22271 } 22272 22273 final PackageStats stats = new PackageStats(null, -1); 22274 synchronized (mInstaller) { 22275 for (int userId : installedUserIds) { 22276 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 22277 freezer.close(); 22278 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22279 "Failed to measure package size"); 22280 } 22281 } 22282 } 22283 22284 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 22285 + stats.dataSize); 22286 22287 final long startFreeBytes = measurePath.getFreeSpace(); 22288 final long sizeBytes; 22289 if (moveCompleteApp) { 22290 sizeBytes = stats.codeSize + stats.dataSize; 22291 } else { 22292 sizeBytes = stats.codeSize; 22293 } 22294 22295 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 22296 freezer.close(); 22297 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 22298 "Not enough free space to move"); 22299 } 22300 22301 mMoveCallbacks.notifyStatusChanged(moveId, 10); 22302 22303 final CountDownLatch installedLatch = new CountDownLatch(1); 22304 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 22305 @Override 22306 public void onUserActionRequired(Intent intent) throws RemoteException { 22307 throw new IllegalStateException(); 22308 } 22309 22310 @Override 22311 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 22312 Bundle extras) throws RemoteException { 22313 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 22314 + PackageManager.installStatusToString(returnCode, msg)); 22315 22316 installedLatch.countDown(); 22317 freezer.close(); 22318 22319 final int status = PackageManager.installStatusToPublicStatus(returnCode); 22320 switch (status) { 22321 case PackageInstaller.STATUS_SUCCESS: 22322 mMoveCallbacks.notifyStatusChanged(moveId, 22323 PackageManager.MOVE_SUCCEEDED); 22324 break; 22325 case PackageInstaller.STATUS_FAILURE_STORAGE: 22326 mMoveCallbacks.notifyStatusChanged(moveId, 22327 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 22328 break; 22329 default: 22330 mMoveCallbacks.notifyStatusChanged(moveId, 22331 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 22332 break; 22333 } 22334 } 22335 }; 22336 22337 final MoveInfo move; 22338 if (moveCompleteApp) { 22339 // Kick off a thread to report progress estimates 22340 new Thread() { 22341 @Override 22342 public void run() { 22343 while (true) { 22344 try { 22345 if (installedLatch.await(1, TimeUnit.SECONDS)) { 22346 break; 22347 } 22348 } catch (InterruptedException ignored) { 22349 } 22350 22351 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 22352 final int progress = 10 + (int) MathUtils.constrain( 22353 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 22354 mMoveCallbacks.notifyStatusChanged(moveId, progress); 22355 } 22356 } 22357 }.start(); 22358 22359 final String dataAppName = codeFile.getName(); 22360 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 22361 dataAppName, appId, seinfo, targetSdkVersion); 22362 } else { 22363 move = null; 22364 } 22365 22366 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 22367 22368 final Message msg = mHandler.obtainMessage(INIT_COPY); 22369 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 22370 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 22371 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 22372 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/, 22373 PackageManager.INSTALL_REASON_UNKNOWN); 22374 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 22375 msg.obj = params; 22376 22377 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 22378 System.identityHashCode(msg.obj)); 22379 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 22380 System.identityHashCode(msg.obj)); 22381 22382 mHandler.sendMessage(msg); 22383 } 22384 22385 @Override 22386 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 22387 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 22388 22389 final int realMoveId = mNextMoveId.getAndIncrement(); 22390 final Bundle extras = new Bundle(); 22391 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 22392 mMoveCallbacks.notifyCreated(realMoveId, extras); 22393 22394 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 22395 @Override 22396 public void onCreated(int moveId, Bundle extras) { 22397 // Ignored 22398 } 22399 22400 @Override 22401 public void onStatusChanged(int moveId, int status, long estMillis) { 22402 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 22403 } 22404 }; 22405 22406 final StorageManager storage = mContext.getSystemService(StorageManager.class); 22407 storage.setPrimaryStorageUuid(volumeUuid, callback); 22408 return realMoveId; 22409 } 22410 22411 @Override 22412 public int getMoveStatus(int moveId) { 22413 mContext.enforceCallingOrSelfPermission( 22414 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22415 return mMoveCallbacks.mLastStatus.get(moveId); 22416 } 22417 22418 @Override 22419 public void registerMoveCallback(IPackageMoveObserver callback) { 22420 mContext.enforceCallingOrSelfPermission( 22421 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22422 mMoveCallbacks.register(callback); 22423 } 22424 22425 @Override 22426 public void unregisterMoveCallback(IPackageMoveObserver callback) { 22427 mContext.enforceCallingOrSelfPermission( 22428 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 22429 mMoveCallbacks.unregister(callback); 22430 } 22431 22432 @Override 22433 public boolean setInstallLocation(int loc) { 22434 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 22435 null); 22436 if (getInstallLocation() == loc) { 22437 return true; 22438 } 22439 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 22440 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 22441 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 22442 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 22443 return true; 22444 } 22445 return false; 22446 } 22447 22448 @Override 22449 public int getInstallLocation() { 22450 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 22451 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 22452 PackageHelper.APP_INSTALL_AUTO); 22453 } 22454 22455 /** Called by UserManagerService */ 22456 void cleanUpUser(UserManagerService userManager, int userHandle) { 22457 synchronized (mPackages) { 22458 mDirtyUsers.remove(userHandle); 22459 mUserNeedsBadging.delete(userHandle); 22460 mSettings.removeUserLPw(userHandle); 22461 mPendingBroadcasts.remove(userHandle); 22462 mInstantAppRegistry.onUserRemovedLPw(userHandle); 22463 removeUnusedPackagesLPw(userManager, userHandle); 22464 } 22465 } 22466 22467 /** 22468 * We're removing userHandle and would like to remove any downloaded packages 22469 * that are no longer in use by any other user. 22470 * @param userHandle the user being removed 22471 */ 22472 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 22473 final boolean DEBUG_CLEAN_APKS = false; 22474 int [] users = userManager.getUserIds(); 22475 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 22476 while (psit.hasNext()) { 22477 PackageSetting ps = psit.next(); 22478 if (ps.pkg == null) { 22479 continue; 22480 } 22481 final String packageName = ps.pkg.packageName; 22482 // Skip over if system app 22483 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 22484 continue; 22485 } 22486 if (DEBUG_CLEAN_APKS) { 22487 Slog.i(TAG, "Checking package " + packageName); 22488 } 22489 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 22490 if (keep) { 22491 if (DEBUG_CLEAN_APKS) { 22492 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 22493 } 22494 } else { 22495 for (int i = 0; i < users.length; i++) { 22496 if (users[i] != userHandle && ps.getInstalled(users[i])) { 22497 keep = true; 22498 if (DEBUG_CLEAN_APKS) { 22499 Slog.i(TAG, " Keeping package " + packageName + " for user " 22500 + users[i]); 22501 } 22502 break; 22503 } 22504 } 22505 } 22506 if (!keep) { 22507 if (DEBUG_CLEAN_APKS) { 22508 Slog.i(TAG, " Removing package " + packageName); 22509 } 22510 mHandler.post(new Runnable() { 22511 public void run() { 22512 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, 22513 userHandle, 0); 22514 } //end run 22515 }); 22516 } 22517 } 22518 } 22519 22520 /** Called by UserManagerService */ 22521 void createNewUser(int userId, String[] disallowedPackages) { 22522 synchronized (mInstallLock) { 22523 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages); 22524 } 22525 synchronized (mPackages) { 22526 scheduleWritePackageRestrictionsLocked(userId); 22527 scheduleWritePackageListLocked(userId); 22528 applyFactoryDefaultBrowserLPw(userId); 22529 primeDomainVerificationsLPw(userId); 22530 } 22531 } 22532 22533 void onNewUserCreated(final int userId) { 22534 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 22535 // If permission review for legacy apps is required, we represent 22536 // dagerous permissions for such apps as always granted runtime 22537 // permissions to keep per user flag state whether review is needed. 22538 // Hence, if a new user is added we have to propagate dangerous 22539 // permission grants for these legacy apps. 22540 if (mPermissionReviewRequired) { 22541 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 22542 | UPDATE_PERMISSIONS_REPLACE_ALL); 22543 } 22544 } 22545 22546 @Override 22547 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 22548 mContext.enforceCallingOrSelfPermission( 22549 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 22550 "Only package verification agents can read the verifier device identity"); 22551 22552 synchronized (mPackages) { 22553 return mSettings.getVerifierDeviceIdentityLPw(); 22554 } 22555 } 22556 22557 @Override 22558 public void setPermissionEnforced(String permission, boolean enforced) { 22559 // TODO: Now that we no longer change GID for storage, this should to away. 22560 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 22561 "setPermissionEnforced"); 22562 if (READ_EXTERNAL_STORAGE.equals(permission)) { 22563 synchronized (mPackages) { 22564 if (mSettings.mReadExternalStorageEnforced == null 22565 || mSettings.mReadExternalStorageEnforced != enforced) { 22566 mSettings.mReadExternalStorageEnforced = enforced; 22567 mSettings.writeLPr(); 22568 } 22569 } 22570 // kill any non-foreground processes so we restart them and 22571 // grant/revoke the GID. 22572 final IActivityManager am = ActivityManager.getService(); 22573 if (am != null) { 22574 final long token = Binder.clearCallingIdentity(); 22575 try { 22576 am.killProcessesBelowForeground("setPermissionEnforcement"); 22577 } catch (RemoteException e) { 22578 } finally { 22579 Binder.restoreCallingIdentity(token); 22580 } 22581 } 22582 } else { 22583 throw new IllegalArgumentException("No selective enforcement for " + permission); 22584 } 22585 } 22586 22587 @Override 22588 @Deprecated 22589 public boolean isPermissionEnforced(String permission) { 22590 return true; 22591 } 22592 22593 @Override 22594 public boolean isStorageLow() { 22595 final long token = Binder.clearCallingIdentity(); 22596 try { 22597 final DeviceStorageMonitorInternal 22598 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 22599 if (dsm != null) { 22600 return dsm.isMemoryLow(); 22601 } else { 22602 return false; 22603 } 22604 } finally { 22605 Binder.restoreCallingIdentity(token); 22606 } 22607 } 22608 22609 @Override 22610 public IPackageInstaller getPackageInstaller() { 22611 return mInstallerService; 22612 } 22613 22614 private boolean userNeedsBadging(int userId) { 22615 int index = mUserNeedsBadging.indexOfKey(userId); 22616 if (index < 0) { 22617 final UserInfo userInfo; 22618 final long token = Binder.clearCallingIdentity(); 22619 try { 22620 userInfo = sUserManager.getUserInfo(userId); 22621 } finally { 22622 Binder.restoreCallingIdentity(token); 22623 } 22624 final boolean b; 22625 if (userInfo != null && userInfo.isManagedProfile()) { 22626 b = true; 22627 } else { 22628 b = false; 22629 } 22630 mUserNeedsBadging.put(userId, b); 22631 return b; 22632 } 22633 return mUserNeedsBadging.valueAt(index); 22634 } 22635 22636 @Override 22637 public KeySet getKeySetByAlias(String packageName, String alias) { 22638 if (packageName == null || alias == null) { 22639 return null; 22640 } 22641 synchronized(mPackages) { 22642 final PackageParser.Package pkg = mPackages.get(packageName); 22643 if (pkg == null) { 22644 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22645 throw new IllegalArgumentException("Unknown package: " + packageName); 22646 } 22647 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22648 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 22649 } 22650 } 22651 22652 @Override 22653 public KeySet getSigningKeySet(String packageName) { 22654 if (packageName == null) { 22655 return null; 22656 } 22657 synchronized(mPackages) { 22658 final PackageParser.Package pkg = mPackages.get(packageName); 22659 if (pkg == null) { 22660 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22661 throw new IllegalArgumentException("Unknown package: " + packageName); 22662 } 22663 if (pkg.applicationInfo.uid != Binder.getCallingUid() 22664 && Process.SYSTEM_UID != Binder.getCallingUid()) { 22665 throw new SecurityException("May not access signing KeySet of other apps."); 22666 } 22667 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22668 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 22669 } 22670 } 22671 22672 @Override 22673 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 22674 if (packageName == null || ks == null) { 22675 return false; 22676 } 22677 synchronized(mPackages) { 22678 final PackageParser.Package pkg = mPackages.get(packageName); 22679 if (pkg == null) { 22680 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22681 throw new IllegalArgumentException("Unknown package: " + packageName); 22682 } 22683 IBinder ksh = ks.getToken(); 22684 if (ksh instanceof KeySetHandle) { 22685 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22686 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 22687 } 22688 return false; 22689 } 22690 } 22691 22692 @Override 22693 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 22694 if (packageName == null || ks == null) { 22695 return false; 22696 } 22697 synchronized(mPackages) { 22698 final PackageParser.Package pkg = mPackages.get(packageName); 22699 if (pkg == null) { 22700 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 22701 throw new IllegalArgumentException("Unknown package: " + packageName); 22702 } 22703 IBinder ksh = ks.getToken(); 22704 if (ksh instanceof KeySetHandle) { 22705 KeySetManagerService ksms = mSettings.mKeySetManagerService; 22706 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 22707 } 22708 return false; 22709 } 22710 } 22711 22712 private void deletePackageIfUnusedLPr(final String packageName) { 22713 PackageSetting ps = mSettings.mPackages.get(packageName); 22714 if (ps == null) { 22715 return; 22716 } 22717 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 22718 // TODO Implement atomic delete if package is unused 22719 // It is currently possible that the package will be deleted even if it is installed 22720 // after this method returns. 22721 mHandler.post(new Runnable() { 22722 public void run() { 22723 deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST, 22724 0, PackageManager.DELETE_ALL_USERS); 22725 } 22726 }); 22727 } 22728 } 22729 22730 /** 22731 * Check and throw if the given before/after packages would be considered a 22732 * downgrade. 22733 */ 22734 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 22735 throws PackageManagerException { 22736 if (after.versionCode < before.mVersionCode) { 22737 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22738 "Update version code " + after.versionCode + " is older than current " 22739 + before.mVersionCode); 22740 } else if (after.versionCode == before.mVersionCode) { 22741 if (after.baseRevisionCode < before.baseRevisionCode) { 22742 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22743 "Update base revision code " + after.baseRevisionCode 22744 + " is older than current " + before.baseRevisionCode); 22745 } 22746 22747 if (!ArrayUtils.isEmpty(after.splitNames)) { 22748 for (int i = 0; i < after.splitNames.length; i++) { 22749 final String splitName = after.splitNames[i]; 22750 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 22751 if (j != -1) { 22752 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 22753 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 22754 "Update split " + splitName + " revision code " 22755 + after.splitRevisionCodes[i] + " is older than current " 22756 + before.splitRevisionCodes[j]); 22757 } 22758 } 22759 } 22760 } 22761 } 22762 } 22763 22764 private static class MoveCallbacks extends Handler { 22765 private static final int MSG_CREATED = 1; 22766 private static final int MSG_STATUS_CHANGED = 2; 22767 22768 private final RemoteCallbackList<IPackageMoveObserver> 22769 mCallbacks = new RemoteCallbackList<>(); 22770 22771 private final SparseIntArray mLastStatus = new SparseIntArray(); 22772 22773 public MoveCallbacks(Looper looper) { 22774 super(looper); 22775 } 22776 22777 public void register(IPackageMoveObserver callback) { 22778 mCallbacks.register(callback); 22779 } 22780 22781 public void unregister(IPackageMoveObserver callback) { 22782 mCallbacks.unregister(callback); 22783 } 22784 22785 @Override 22786 public void handleMessage(Message msg) { 22787 final SomeArgs args = (SomeArgs) msg.obj; 22788 final int n = mCallbacks.beginBroadcast(); 22789 for (int i = 0; i < n; i++) { 22790 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 22791 try { 22792 invokeCallback(callback, msg.what, args); 22793 } catch (RemoteException ignored) { 22794 } 22795 } 22796 mCallbacks.finishBroadcast(); 22797 args.recycle(); 22798 } 22799 22800 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 22801 throws RemoteException { 22802 switch (what) { 22803 case MSG_CREATED: { 22804 callback.onCreated(args.argi1, (Bundle) args.arg2); 22805 break; 22806 } 22807 case MSG_STATUS_CHANGED: { 22808 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 22809 break; 22810 } 22811 } 22812 } 22813 22814 private void notifyCreated(int moveId, Bundle extras) { 22815 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 22816 22817 final SomeArgs args = SomeArgs.obtain(); 22818 args.argi1 = moveId; 22819 args.arg2 = extras; 22820 obtainMessage(MSG_CREATED, args).sendToTarget(); 22821 } 22822 22823 private void notifyStatusChanged(int moveId, int status) { 22824 notifyStatusChanged(moveId, status, -1); 22825 } 22826 22827 private void notifyStatusChanged(int moveId, int status, long estMillis) { 22828 Slog.v(TAG, "Move " + moveId + " status " + status); 22829 22830 final SomeArgs args = SomeArgs.obtain(); 22831 args.argi1 = moveId; 22832 args.argi2 = status; 22833 args.arg3 = estMillis; 22834 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 22835 22836 synchronized (mLastStatus) { 22837 mLastStatus.put(moveId, status); 22838 } 22839 } 22840 } 22841 22842 private final static class OnPermissionChangeListeners extends Handler { 22843 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 22844 22845 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 22846 new RemoteCallbackList<>(); 22847 22848 public OnPermissionChangeListeners(Looper looper) { 22849 super(looper); 22850 } 22851 22852 @Override 22853 public void handleMessage(Message msg) { 22854 switch (msg.what) { 22855 case MSG_ON_PERMISSIONS_CHANGED: { 22856 final int uid = msg.arg1; 22857 handleOnPermissionsChanged(uid); 22858 } break; 22859 } 22860 } 22861 22862 public void addListenerLocked(IOnPermissionsChangeListener listener) { 22863 mPermissionListeners.register(listener); 22864 22865 } 22866 22867 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 22868 mPermissionListeners.unregister(listener); 22869 } 22870 22871 public void onPermissionsChanged(int uid) { 22872 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 22873 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 22874 } 22875 } 22876 22877 private void handleOnPermissionsChanged(int uid) { 22878 final int count = mPermissionListeners.beginBroadcast(); 22879 try { 22880 for (int i = 0; i < count; i++) { 22881 IOnPermissionsChangeListener callback = mPermissionListeners 22882 .getBroadcastItem(i); 22883 try { 22884 callback.onPermissionsChanged(uid); 22885 } catch (RemoteException e) { 22886 Log.e(TAG, "Permission listener is dead", e); 22887 } 22888 } 22889 } finally { 22890 mPermissionListeners.finishBroadcast(); 22891 } 22892 } 22893 } 22894 22895 private class PackageManagerInternalImpl extends PackageManagerInternal { 22896 @Override 22897 public void setLocationPackagesProvider(PackagesProvider provider) { 22898 synchronized (mPackages) { 22899 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 22900 } 22901 } 22902 22903 @Override 22904 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 22905 synchronized (mPackages) { 22906 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 22907 } 22908 } 22909 22910 @Override 22911 public void setSmsAppPackagesProvider(PackagesProvider provider) { 22912 synchronized (mPackages) { 22913 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 22914 } 22915 } 22916 22917 @Override 22918 public void setDialerAppPackagesProvider(PackagesProvider provider) { 22919 synchronized (mPackages) { 22920 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 22921 } 22922 } 22923 22924 @Override 22925 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 22926 synchronized (mPackages) { 22927 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 22928 } 22929 } 22930 22931 @Override 22932 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 22933 synchronized (mPackages) { 22934 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 22935 } 22936 } 22937 22938 @Override 22939 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 22940 synchronized (mPackages) { 22941 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 22942 packageName, userId); 22943 } 22944 } 22945 22946 @Override 22947 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 22948 synchronized (mPackages) { 22949 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 22950 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 22951 packageName, userId); 22952 } 22953 } 22954 22955 @Override 22956 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 22957 synchronized (mPackages) { 22958 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 22959 packageName, userId); 22960 } 22961 } 22962 22963 @Override 22964 public void setKeepUninstalledPackages(final List<String> packageList) { 22965 Preconditions.checkNotNull(packageList); 22966 List<String> removedFromList = null; 22967 synchronized (mPackages) { 22968 if (mKeepUninstalledPackages != null) { 22969 final int packagesCount = mKeepUninstalledPackages.size(); 22970 for (int i = 0; i < packagesCount; i++) { 22971 String oldPackage = mKeepUninstalledPackages.get(i); 22972 if (packageList != null && packageList.contains(oldPackage)) { 22973 continue; 22974 } 22975 if (removedFromList == null) { 22976 removedFromList = new ArrayList<>(); 22977 } 22978 removedFromList.add(oldPackage); 22979 } 22980 } 22981 mKeepUninstalledPackages = new ArrayList<>(packageList); 22982 if (removedFromList != null) { 22983 final int removedCount = removedFromList.size(); 22984 for (int i = 0; i < removedCount; i++) { 22985 deletePackageIfUnusedLPr(removedFromList.get(i)); 22986 } 22987 } 22988 } 22989 } 22990 22991 @Override 22992 public boolean isPermissionsReviewRequired(String packageName, int userId) { 22993 synchronized (mPackages) { 22994 // If we do not support permission review, done. 22995 if (!mPermissionReviewRequired) { 22996 return false; 22997 } 22998 22999 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 23000 if (packageSetting == null) { 23001 return false; 23002 } 23003 23004 // Permission review applies only to apps not supporting the new permission model. 23005 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 23006 return false; 23007 } 23008 23009 // Legacy apps have the permission and get user consent on launch. 23010 PermissionsState permissionsState = packageSetting.getPermissionsState(); 23011 return permissionsState.isPermissionReviewRequired(userId); 23012 } 23013 } 23014 23015 @Override 23016 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 23017 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 23018 } 23019 23020 @Override 23021 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 23022 int userId) { 23023 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 23024 } 23025 23026 @Override 23027 public void setDeviceAndProfileOwnerPackages( 23028 int deviceOwnerUserId, String deviceOwnerPackage, 23029 SparseArray<String> profileOwnerPackages) { 23030 mProtectedPackages.setDeviceAndProfileOwnerPackages( 23031 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 23032 } 23033 23034 @Override 23035 public boolean isPackageDataProtected(int userId, String packageName) { 23036 return mProtectedPackages.isPackageDataProtected(userId, packageName); 23037 } 23038 23039 @Override 23040 public boolean isPackageEphemeral(int userId, String packageName) { 23041 synchronized (mPackages) { 23042 final PackageSetting ps = mSettings.mPackages.get(packageName); 23043 return ps != null ? ps.getInstantApp(userId) : false; 23044 } 23045 } 23046 23047 @Override 23048 public boolean wasPackageEverLaunched(String packageName, int userId) { 23049 synchronized (mPackages) { 23050 return mSettings.wasPackageEverLaunchedLPr(packageName, userId); 23051 } 23052 } 23053 23054 @Override 23055 public void grantRuntimePermission(String packageName, String name, int userId, 23056 boolean overridePolicy) { 23057 PackageManagerService.this.grantRuntimePermission(packageName, name, userId, 23058 overridePolicy); 23059 } 23060 23061 @Override 23062 public void revokeRuntimePermission(String packageName, String name, int userId, 23063 boolean overridePolicy) { 23064 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId, 23065 overridePolicy); 23066 } 23067 23068 @Override 23069 public String getNameForUid(int uid) { 23070 return PackageManagerService.this.getNameForUid(uid); 23071 } 23072 23073 @Override 23074 public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, 23075 Intent origIntent, String resolvedType, String callingPackage, int userId) { 23076 PackageManagerService.this.requestInstantAppResolutionPhaseTwo( 23077 responseObj, origIntent, resolvedType, callingPackage, userId); 23078 } 23079 23080 @Override 23081 public void grantEphemeralAccess(int userId, Intent intent, 23082 int targetAppId, int ephemeralAppId) { 23083 synchronized (mPackages) { 23084 mInstantAppRegistry.grantInstantAccessLPw(userId, intent, 23085 targetAppId, ephemeralAppId); 23086 } 23087 } 23088 23089 @Override 23090 public void pruneInstantApps() { 23091 synchronized (mPackages) { 23092 mInstantAppRegistry.pruneInstantAppsLPw(); 23093 } 23094 } 23095 23096 @Override 23097 public String getSetupWizardPackageName() { 23098 return mSetupWizardPackage; 23099 } 23100 23101 public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) { 23102 if (policy != null) { 23103 mExternalSourcesPolicy = policy; 23104 } 23105 } 23106 23107 @Override 23108 public boolean isPackagePersistent(String packageName) { 23109 synchronized (mPackages) { 23110 PackageParser.Package pkg = mPackages.get(packageName); 23111 return pkg != null 23112 ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM 23113 | ApplicationInfo.FLAG_PERSISTENT)) == 23114 (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT)) 23115 : false; 23116 } 23117 } 23118 23119 @Override 23120 public List<PackageInfo> getOverlayPackages(int userId) { 23121 final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>(); 23122 synchronized (mPackages) { 23123 for (PackageParser.Package p : mPackages.values()) { 23124 if (p.mOverlayTarget != null) { 23125 PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId); 23126 if (pkg != null) { 23127 overlayPackages.add(pkg); 23128 } 23129 } 23130 } 23131 } 23132 return overlayPackages; 23133 } 23134 23135 @Override 23136 public List<String> getTargetPackageNames(int userId) { 23137 List<String> targetPackages = new ArrayList<>(); 23138 synchronized (mPackages) { 23139 for (PackageParser.Package p : mPackages.values()) { 23140 if (p.mOverlayTarget == null) { 23141 targetPackages.add(p.packageName); 23142 } 23143 } 23144 } 23145 return targetPackages; 23146 } 23147 23148 @Override 23149 public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName, 23150 @Nullable List<String> overlayPackageNames) { 23151 synchronized (mPackages) { 23152 if (targetPackageName == null || mPackages.get(targetPackageName) == null) { 23153 Slog.e(TAG, "failed to find package " + targetPackageName); 23154 return false; 23155 } 23156 23157 ArrayList<String> paths = null; 23158 if (overlayPackageNames != null) { 23159 final int N = overlayPackageNames.size(); 23160 paths = new ArrayList<>(N); 23161 for (int i = 0; i < N; i++) { 23162 final String packageName = overlayPackageNames.get(i); 23163 final PackageParser.Package pkg = mPackages.get(packageName); 23164 if (pkg == null) { 23165 Slog.e(TAG, "failed to find package " + packageName); 23166 return false; 23167 } 23168 paths.add(pkg.baseCodePath); 23169 } 23170 } 23171 23172 ArrayMap<String, ArrayList<String>> userSpecificOverlays = 23173 mEnabledOverlayPaths.get(userId); 23174 if (userSpecificOverlays == null) { 23175 userSpecificOverlays = new ArrayMap<>(); 23176 mEnabledOverlayPaths.put(userId, userSpecificOverlays); 23177 } 23178 23179 if (paths != null && paths.size() > 0) { 23180 userSpecificOverlays.put(targetPackageName, paths); 23181 } else { 23182 userSpecificOverlays.remove(targetPackageName); 23183 } 23184 return true; 23185 } 23186 } 23187 23188 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 23189 int flags, int userId) { 23190 return resolveIntentInternal( 23191 intent, resolvedType, flags, userId, true /*includeInstantApp*/); 23192 } 23193 23194 23195 @Override 23196 public void addIsolatedUid(int isolatedUid, int ownerUid) { 23197 synchronized (mPackages) { 23198 mIsolatedOwners.put(isolatedUid, ownerUid); 23199 } 23200 } 23201 23202 @Override 23203 public void removeIsolatedUid(int isolatedUid) { 23204 synchronized (mPackages) { 23205 mIsolatedOwners.delete(isolatedUid); 23206 } 23207 } 23208 } 23209 23210 @Override 23211 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 23212 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 23213 synchronized (mPackages) { 23214 final long identity = Binder.clearCallingIdentity(); 23215 try { 23216 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 23217 packageNames, userId); 23218 } finally { 23219 Binder.restoreCallingIdentity(identity); 23220 } 23221 } 23222 } 23223 23224 @Override 23225 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) { 23226 enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices"); 23227 synchronized (mPackages) { 23228 final long identity = Binder.clearCallingIdentity(); 23229 try { 23230 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr( 23231 packageNames, userId); 23232 } finally { 23233 Binder.restoreCallingIdentity(identity); 23234 } 23235 } 23236 } 23237 23238 private static void enforceSystemOrPhoneCaller(String tag) { 23239 int callingUid = Binder.getCallingUid(); 23240 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 23241 throw new SecurityException( 23242 "Cannot call " + tag + " from UID " + callingUid); 23243 } 23244 } 23245 23246 boolean isHistoricalPackageUsageAvailable() { 23247 return mPackageUsage.isHistoricalPackageUsageAvailable(); 23248 } 23249 23250 /** 23251 * Return a <b>copy</b> of the collection of packages known to the package manager. 23252 * @return A copy of the values of mPackages. 23253 */ 23254 Collection<PackageParser.Package> getPackages() { 23255 synchronized (mPackages) { 23256 return new ArrayList<>(mPackages.values()); 23257 } 23258 } 23259 23260 /** 23261 * Logs process start information (including base APK hash) to the security log. 23262 * @hide 23263 */ 23264 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 23265 String apkFile, int pid) { 23266 if (!SecurityLog.isLoggingEnabled()) { 23267 return; 23268 } 23269 Bundle data = new Bundle(); 23270 data.putLong("startTimestamp", System.currentTimeMillis()); 23271 data.putString("processName", processName); 23272 data.putInt("uid", uid); 23273 data.putString("seinfo", seinfo); 23274 data.putString("apkFile", apkFile); 23275 data.putInt("pid", pid); 23276 Message msg = mProcessLoggingHandler.obtainMessage( 23277 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 23278 msg.setData(data); 23279 mProcessLoggingHandler.sendMessage(msg); 23280 } 23281 23282 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 23283 return mCompilerStats.getPackageStats(pkgName); 23284 } 23285 23286 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 23287 return getOrCreateCompilerPackageStats(pkg.packageName); 23288 } 23289 23290 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 23291 return mCompilerStats.getOrCreatePackageStats(pkgName); 23292 } 23293 23294 public void deleteCompilerPackageStats(String pkgName) { 23295 mCompilerStats.deletePackageStats(pkgName); 23296 } 23297 23298 @Override 23299 public int getInstallReason(String packageName, int userId) { 23300 enforceCrossUserPermission(Binder.getCallingUid(), userId, 23301 true /* requireFullPermission */, false /* checkShell */, 23302 "get install reason"); 23303 synchronized (mPackages) { 23304 final PackageSetting ps = mSettings.mPackages.get(packageName); 23305 if (ps != null) { 23306 return ps.getInstallReason(userId); 23307 } 23308 } 23309 return PackageManager.INSTALL_REASON_UNKNOWN; 23310 } 23311 23312 @Override 23313 public boolean canRequestPackageInstalls(String packageName, int userId) { 23314 int callingUid = Binder.getCallingUid(); 23315 int uid = getPackageUid(packageName, 0, userId); 23316 if (callingUid != uid && callingUid != Process.ROOT_UID 23317 && callingUid != Process.SYSTEM_UID) { 23318 throw new SecurityException( 23319 "Caller uid " + callingUid + " does not own package " + packageName); 23320 } 23321 ApplicationInfo info = getApplicationInfo(packageName, 0, userId); 23322 if (info == null) { 23323 return false; 23324 } 23325 if (info.targetSdkVersion < Build.VERSION_CODES.O) { 23326 throw new UnsupportedOperationException( 23327 "Operation only supported on apps targeting Android O or higher"); 23328 } 23329 String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES; 23330 String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission); 23331 if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) { 23332 throw new SecurityException("Need to declare " + appOpPermission + " to call this api"); 23333 } 23334 if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) { 23335 return false; 23336 } 23337 if (mExternalSourcesPolicy != null) { 23338 int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid); 23339 if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) { 23340 return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED; 23341 } 23342 } 23343 return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED; 23344 } 23345} 23346