PackageManagerService.java revision a34f53f61be31b7171d6cbcb12490ee143acffff
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.READ_EXTERNAL_STORAGE; 20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 21import static android.Manifest.permission.WRITE_MEDIA_STORAGE; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 27import static android.content.pm.PackageManager.DELETE_KEEP_DATA; 28import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 29import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 30import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 31import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 32import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 33import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 35import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 36import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 37import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 38import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 40import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; 41import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 42import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 43import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 45import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 46import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 47import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 48import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 49import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 50import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 51import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 52import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 53import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 54import static android.content.pm.PackageManager.INSTALL_INTERNAL; 55import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 56import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 61import static android.content.pm.PackageManager.MATCH_ALL; 62import static android.content.pm.PackageManager.MATCH_ANY_USER; 63import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 65import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 66import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 67import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; 68import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES; 69import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 70import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 71import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 72import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 73import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 74import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 75import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 76import static android.content.pm.PackageManager.PERMISSION_DENIED; 77import static android.content.pm.PackageManager.PERMISSION_GRANTED; 78import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 79import static android.content.pm.PackageParser.isApkFile; 80import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 81import static android.system.OsConstants.O_CREAT; 82import static android.system.OsConstants.O_RDWR; 83 84import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 85import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 86import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 87import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 88import static com.android.internal.util.ArrayUtils.appendInt; 89import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 90import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 91import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 92import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 93import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 94import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 95import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 96import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 97import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter; 98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 99import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 100import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 101 102import android.Manifest; 103import android.annotation.NonNull; 104import android.annotation.Nullable; 105import android.app.ActivityManager; 106import android.app.AppOpsManager; 107import android.app.IActivityManager; 108import android.app.ResourcesManager; 109import android.app.admin.IDevicePolicyManager; 110import android.app.admin.SecurityLog; 111import android.app.backup.IBackupManager; 112import android.content.BroadcastReceiver; 113import android.content.ComponentName; 114import android.content.ContentResolver; 115import android.content.Context; 116import android.content.IIntentReceiver; 117import android.content.Intent; 118import android.content.IntentFilter; 119import android.content.IntentSender; 120import android.content.IntentSender.SendIntentException; 121import android.content.ServiceConnection; 122import android.content.pm.ActivityInfo; 123import android.content.pm.ApplicationInfo; 124import android.content.pm.AppsQueryHelper; 125import android.content.pm.ComponentInfo; 126import android.content.pm.EphemeralApplicationInfo; 127import android.content.pm.EphemeralRequest; 128import android.content.pm.EphemeralResolveInfo; 129import android.content.pm.EphemeralResponse; 130import android.content.pm.FallbackCategoryProvider; 131import android.content.pm.FeatureInfo; 132import android.content.pm.IOnPermissionsChangeListener; 133import android.content.pm.IPackageDataObserver; 134import android.content.pm.IPackageDeleteObserver; 135import android.content.pm.IPackageDeleteObserver2; 136import android.content.pm.IPackageInstallObserver2; 137import android.content.pm.IPackageInstaller; 138import android.content.pm.IPackageManager; 139import android.content.pm.IPackageMoveObserver; 140import android.content.pm.IPackageStatsObserver; 141import android.content.pm.InstrumentationInfo; 142import android.content.pm.IntentFilterVerificationInfo; 143import android.content.pm.KeySet; 144import android.content.pm.PackageCleanItem; 145import android.content.pm.PackageInfo; 146import android.content.pm.PackageInfoLite; 147import android.content.pm.PackageInstaller; 148import android.content.pm.PackageManager; 149import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 150import android.content.pm.PackageManagerInternal; 151import android.content.pm.PackageParser; 152import android.content.pm.PackageParser.ActivityIntentInfo; 153import android.content.pm.PackageParser.PackageLite; 154import android.content.pm.PackageParser.PackageParserException; 155import android.content.pm.PackageStats; 156import android.content.pm.PackageUserState; 157import android.content.pm.ParceledListSlice; 158import android.content.pm.PermissionGroupInfo; 159import android.content.pm.PermissionInfo; 160import android.content.pm.ProviderInfo; 161import android.content.pm.ResolveInfo; 162import android.content.pm.ServiceInfo; 163import android.content.pm.Signature; 164import android.content.pm.UserInfo; 165import android.content.pm.VerifierDeviceIdentity; 166import android.content.pm.VerifierInfo; 167import android.content.res.Resources; 168import android.graphics.Bitmap; 169import android.hardware.display.DisplayManager; 170import android.net.Uri; 171import android.os.Binder; 172import android.os.Build; 173import android.os.Bundle; 174import android.os.Debug; 175import android.os.Environment; 176import android.os.Environment.UserEnvironment; 177import android.os.FileUtils; 178import android.os.Handler; 179import android.os.IBinder; 180import android.os.Looper; 181import android.os.Message; 182import android.os.Parcel; 183import android.os.ParcelFileDescriptor; 184import android.os.PatternMatcher; 185import android.os.Process; 186import android.os.RemoteCallbackList; 187import android.os.RemoteException; 188import android.os.ResultReceiver; 189import android.os.SELinux; 190import android.os.ServiceManager; 191import android.os.ShellCallback; 192import android.os.SystemClock; 193import android.os.SystemProperties; 194import android.os.Trace; 195import android.os.UserHandle; 196import android.os.UserManager; 197import android.os.UserManagerInternal; 198import android.os.storage.IStorageManager; 199import android.os.storage.StorageManagerInternal; 200import android.os.storage.StorageEventListener; 201import android.os.storage.StorageManager; 202import android.os.storage.VolumeInfo; 203import android.os.storage.VolumeRecord; 204import android.provider.Settings.Global; 205import android.provider.Settings.Secure; 206import android.security.KeyStore; 207import android.security.SystemKeyStore; 208import android.system.ErrnoException; 209import android.system.Os; 210import android.text.TextUtils; 211import android.text.format.DateUtils; 212import android.util.ArrayMap; 213import android.util.ArraySet; 214import android.util.Base64; 215import android.util.DisplayMetrics; 216import android.util.EventLog; 217import android.util.ExceptionUtils; 218import android.util.Log; 219import android.util.LogPrinter; 220import android.util.MathUtils; 221import android.util.Pair; 222import android.util.PrintStreamPrinter; 223import android.util.Slog; 224import android.util.SparseArray; 225import android.util.SparseBooleanArray; 226import android.util.SparseIntArray; 227import android.util.Xml; 228import android.util.jar.StrictJarFile; 229import android.view.Display; 230 231import com.android.internal.R; 232import com.android.internal.annotations.GuardedBy; 233import com.android.internal.app.IMediaContainerService; 234import com.android.internal.app.ResolverActivity; 235import com.android.internal.content.NativeLibraryHelper; 236import com.android.internal.content.PackageHelper; 237import com.android.internal.logging.MetricsLogger; 238import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 239import com.android.internal.os.IParcelFileDescriptorFactory; 240import com.android.internal.os.RoSystemProperties; 241import com.android.internal.os.SomeArgs; 242import com.android.internal.os.Zygote; 243import com.android.internal.telephony.CarrierAppUtils; 244import com.android.internal.util.ArrayUtils; 245import com.android.internal.util.FastPrintWriter; 246import com.android.internal.util.FastXmlSerializer; 247import com.android.internal.util.IndentingPrintWriter; 248import com.android.internal.util.Preconditions; 249import com.android.internal.util.XmlUtils; 250import com.android.server.AttributeCache; 251import com.android.server.EventLogTags; 252import com.android.server.FgThread; 253import com.android.server.IntentResolver; 254import com.android.server.LocalServices; 255import com.android.server.ServiceThread; 256import com.android.server.SystemConfig; 257import com.android.server.Watchdog; 258import com.android.server.net.NetworkPolicyManagerInternal; 259import com.android.server.pm.Installer.InstallerException; 260import com.android.server.pm.PermissionsState.PermissionState; 261import com.android.server.pm.Settings.DatabaseVersion; 262import com.android.server.pm.Settings.VersionInfo; 263import com.android.server.pm.dex.DexManager; 264import com.android.server.storage.DeviceStorageMonitorInternal; 265 266import dalvik.system.CloseGuard; 267import dalvik.system.DexFile; 268import dalvik.system.VMRuntime; 269 270import libcore.io.IoUtils; 271import libcore.util.EmptyArray; 272 273import org.xmlpull.v1.XmlPullParser; 274import org.xmlpull.v1.XmlPullParserException; 275import org.xmlpull.v1.XmlSerializer; 276 277import java.io.BufferedOutputStream; 278import java.io.BufferedReader; 279import java.io.ByteArrayInputStream; 280import java.io.ByteArrayOutputStream; 281import java.io.File; 282import java.io.FileDescriptor; 283import java.io.FileInputStream; 284import java.io.FileNotFoundException; 285import java.io.FileOutputStream; 286import java.io.FileReader; 287import java.io.FilenameFilter; 288import java.io.IOException; 289import java.io.PrintWriter; 290import java.nio.charset.StandardCharsets; 291import java.security.DigestInputStream; 292import java.security.MessageDigest; 293import java.security.NoSuchAlgorithmException; 294import java.security.PublicKey; 295import java.security.SecureRandom; 296import java.security.cert.Certificate; 297import java.security.cert.CertificateEncodingException; 298import java.security.cert.CertificateException; 299import java.text.SimpleDateFormat; 300import java.util.ArrayList; 301import java.util.Arrays; 302import java.util.Collection; 303import java.util.Collections; 304import java.util.Comparator; 305import java.util.Date; 306import java.util.HashSet; 307import java.util.HashMap; 308import java.util.Iterator; 309import java.util.List; 310import java.util.Map; 311import java.util.Objects; 312import java.util.Set; 313import java.util.concurrent.CountDownLatch; 314import java.util.concurrent.TimeUnit; 315import java.util.concurrent.atomic.AtomicBoolean; 316import java.util.concurrent.atomic.AtomicInteger; 317 318/** 319 * Keep track of all those APKs everywhere. 320 * <p> 321 * Internally there are two important locks: 322 * <ul> 323 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 324 * and other related state. It is a fine-grained lock that should only be held 325 * momentarily, as it's one of the most contended locks in the system. 326 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 327 * operations typically involve heavy lifting of application data on disk. Since 328 * {@code installd} is single-threaded, and it's operations can often be slow, 329 * this lock should never be acquired while already holding {@link #mPackages}. 330 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 331 * holding {@link #mInstallLock}. 332 * </ul> 333 * Many internal methods rely on the caller to hold the appropriate locks, and 334 * this contract is expressed through method name suffixes: 335 * <ul> 336 * <li>fooLI(): the caller must hold {@link #mInstallLock} 337 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 338 * being modified must be frozen 339 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 340 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 341 * </ul> 342 * <p> 343 * Because this class is very central to the platform's security; please run all 344 * CTS and unit tests whenever making modifications: 345 * 346 * <pre> 347 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 348 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases 349 * </pre> 350 */ 351public class PackageManagerService extends IPackageManager.Stub { 352 static final String TAG = "PackageManager"; 353 static final boolean DEBUG_SETTINGS = false; 354 static final boolean DEBUG_PREFERRED = false; 355 static final boolean DEBUG_UPGRADE = false; 356 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 357 private static final boolean DEBUG_BACKUP = false; 358 private static final boolean DEBUG_INSTALL = false; 359 private static final boolean DEBUG_REMOVE = false; 360 private static final boolean DEBUG_BROADCASTS = false; 361 private static final boolean DEBUG_SHOW_INFO = false; 362 private static final boolean DEBUG_PACKAGE_INFO = false; 363 private static final boolean DEBUG_INTENT_MATCHING = false; 364 private static final boolean DEBUG_PACKAGE_SCANNING = false; 365 private static final boolean DEBUG_VERIFY = false; 366 private static final boolean DEBUG_FILTERS = false; 367 368 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 369 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 370 // user, but by default initialize to this. 371 static final boolean DEBUG_DEXOPT = false; 372 373 private static final boolean DEBUG_ABI_SELECTION = false; 374 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 375 private static final boolean DEBUG_TRIAGED_MISSING = false; 376 private static final boolean DEBUG_APP_DATA = false; 377 378 /** REMOVE. According to Svet, this was only used to reset permissions during development. */ 379 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 380 381 private static final boolean DISABLE_EPHEMERAL_APPS = false; 382 private static final boolean HIDE_EPHEMERAL_APIS = true; 383 384 private static final boolean ENABLE_QUOTA = 385 SystemProperties.getBoolean("persist.fw.quota", false); 386 387 private static final int RADIO_UID = Process.PHONE_UID; 388 private static final int LOG_UID = Process.LOG_UID; 389 private static final int NFC_UID = Process.NFC_UID; 390 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 391 private static final int SHELL_UID = Process.SHELL_UID; 392 393 // Cap the size of permission trees that 3rd party apps can define 394 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 395 396 // Suffix used during package installation when copying/moving 397 // package apks to install directory. 398 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 399 400 static final int SCAN_NO_DEX = 1<<1; 401 static final int SCAN_FORCE_DEX = 1<<2; 402 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 403 static final int SCAN_NEW_INSTALL = 1<<4; 404 static final int SCAN_UPDATE_TIME = 1<<5; 405 static final int SCAN_BOOTING = 1<<6; 406 static final int SCAN_TRUSTED_OVERLAY = 1<<7; 407 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8; 408 static final int SCAN_REPLACING = 1<<9; 409 static final int SCAN_REQUIRE_KNOWN = 1<<10; 410 static final int SCAN_MOVE = 1<<11; 411 static final int SCAN_INITIAL = 1<<12; 412 static final int SCAN_CHECK_ONLY = 1<<13; 413 static final int SCAN_DONT_KILL_APP = 1<<14; 414 static final int SCAN_IGNORE_FROZEN = 1<<15; 415 static final int REMOVE_CHATTY = 1<<16; 416 static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<17; 417 418 private static final int[] EMPTY_INT_ARRAY = new int[0]; 419 420 /** 421 * Timeout (in milliseconds) after which the watchdog should declare that 422 * our handler thread is wedged. The usual default for such things is one 423 * minute but we sometimes do very lengthy I/O operations on this thread, 424 * such as installing multi-gigabyte applications, so ours needs to be longer. 425 */ 426 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 427 428 /** 429 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 430 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 431 * settings entry if available, otherwise we use the hardcoded default. If it's been 432 * more than this long since the last fstrim, we force one during the boot sequence. 433 * 434 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 435 * one gets run at the next available charging+idle time. This final mandatory 436 * no-fstrim check kicks in only of the other scheduling criteria is never met. 437 */ 438 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 439 440 /** 441 * Whether verification is enabled by default. 442 */ 443 private static final boolean DEFAULT_VERIFY_ENABLE = true; 444 445 /** 446 * The default maximum time to wait for the verification agent to return in 447 * milliseconds. 448 */ 449 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 450 451 /** 452 * The default response for package verification timeout. 453 * 454 * This can be either PackageManager.VERIFICATION_ALLOW or 455 * PackageManager.VERIFICATION_REJECT. 456 */ 457 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 458 459 static final String PLATFORM_PACKAGE_NAME = "android"; 460 461 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 462 463 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 464 DEFAULT_CONTAINER_PACKAGE, 465 "com.android.defcontainer.DefaultContainerService"); 466 467 private static final String KILL_APP_REASON_GIDS_CHANGED = 468 "permission grant or revoke changed gids"; 469 470 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 471 "permissions revoked"; 472 473 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 474 475 private static final String PACKAGE_SCHEME = "package"; 476 477 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 478 /** 479 * If VENDOR_OVERLAY_THEME_PROPERTY is set, search for runtime resource overlay APKs also in 480 * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_THEME_PROPERTY> in addition to 481 * VENDOR_OVERLAY_DIR. 482 */ 483 private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme"; 484 /** 485 * Same as VENDOR_OVERLAY_THEME_PROPERTY, except persistent. If set will override whatever 486 * is in VENDOR_OVERLAY_THEME_PROPERTY. 487 */ 488 private static final String VENDOR_OVERLAY_THEME_PERSIST_PROPERTY 489 = "persist.vendor.overlay.theme"; 490 491 /** Permission grant: not grant the permission. */ 492 private static final int GRANT_DENIED = 1; 493 494 /** Permission grant: grant the permission as an install permission. */ 495 private static final int GRANT_INSTALL = 2; 496 497 /** Permission grant: grant the permission as a runtime one. */ 498 private static final int GRANT_RUNTIME = 3; 499 500 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 501 private static final int GRANT_UPGRADE = 4; 502 503 /** Canonical intent used to identify what counts as a "web browser" app */ 504 private static final Intent sBrowserIntent; 505 static { 506 sBrowserIntent = new Intent(); 507 sBrowserIntent.setAction(Intent.ACTION_VIEW); 508 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 509 sBrowserIntent.setData(Uri.parse("http:")); 510 } 511 512 /** 513 * The set of all protected actions [i.e. those actions for which a high priority 514 * intent filter is disallowed]. 515 */ 516 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 517 static { 518 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 519 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 520 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 521 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 522 } 523 524 // Compilation reasons. 525 public static final int REASON_FIRST_BOOT = 0; 526 public static final int REASON_BOOT = 1; 527 public static final int REASON_INSTALL = 2; 528 public static final int REASON_BACKGROUND_DEXOPT = 3; 529 public static final int REASON_AB_OTA = 4; 530 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 531 public static final int REASON_SHARED_APK = 6; 532 public static final int REASON_FORCED_DEXOPT = 7; 533 public static final int REASON_CORE_APP = 8; 534 535 public static final int REASON_LAST = REASON_CORE_APP; 536 537 /** Special library name that skips shared libraries check during compilation. */ 538 private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; 539 540 /** All dangerous permission names in the same order as the events in MetricsEvent */ 541 private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList( 542 Manifest.permission.READ_CALENDAR, 543 Manifest.permission.WRITE_CALENDAR, 544 Manifest.permission.CAMERA, 545 Manifest.permission.READ_CONTACTS, 546 Manifest.permission.WRITE_CONTACTS, 547 Manifest.permission.GET_ACCOUNTS, 548 Manifest.permission.ACCESS_FINE_LOCATION, 549 Manifest.permission.ACCESS_COARSE_LOCATION, 550 Manifest.permission.RECORD_AUDIO, 551 Manifest.permission.READ_PHONE_STATE, 552 Manifest.permission.CALL_PHONE, 553 Manifest.permission.READ_CALL_LOG, 554 Manifest.permission.WRITE_CALL_LOG, 555 Manifest.permission.ADD_VOICEMAIL, 556 Manifest.permission.USE_SIP, 557 Manifest.permission.PROCESS_OUTGOING_CALLS, 558 Manifest.permission.READ_CELL_BROADCASTS, 559 Manifest.permission.BODY_SENSORS, 560 Manifest.permission.SEND_SMS, 561 Manifest.permission.RECEIVE_SMS, 562 Manifest.permission.READ_SMS, 563 Manifest.permission.RECEIVE_WAP_PUSH, 564 Manifest.permission.RECEIVE_MMS, 565 Manifest.permission.READ_EXTERNAL_STORAGE, 566 Manifest.permission.WRITE_EXTERNAL_STORAGE, 567 Manifest.permission.READ_PHONE_NUMBER); 568 569 570 /** 571 * Version number for the package parser cache. Increment this whenever the format or 572 * extent of cached data changes. See {@code PackageParser#setCacheDir}. 573 */ 574 private static final String PACKAGE_PARSER_CACHE_VERSION = "1"; 575 576 /** 577 * Whether the package parser cache is enabled. 578 */ 579 private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true; 580 581 final ServiceThread mHandlerThread; 582 583 final PackageHandler mHandler; 584 585 private final ProcessLoggingHandler mProcessLoggingHandler; 586 587 /** 588 * Messages for {@link #mHandler} that need to wait for system ready before 589 * being dispatched. 590 */ 591 private ArrayList<Message> mPostSystemReadyMessages; 592 593 final int mSdkVersion = Build.VERSION.SDK_INT; 594 595 final Context mContext; 596 final boolean mFactoryTest; 597 final boolean mOnlyCore; 598 final DisplayMetrics mMetrics; 599 final int mDefParseFlags; 600 final String[] mSeparateProcesses; 601 final boolean mIsUpgrade; 602 final boolean mIsPreNUpgrade; 603 final boolean mIsPreNMR1Upgrade; 604 605 @GuardedBy("mPackages") 606 private boolean mDexOptDialogShown; 607 608 /** The location for ASEC container files on internal storage. */ 609 final String mAsecInternalPath; 610 611 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 612 // LOCK HELD. Can be called with mInstallLock held. 613 @GuardedBy("mInstallLock") 614 final Installer mInstaller; 615 616 /** Directory where installed third-party apps stored */ 617 final File mAppInstallDir; 618 final File mEphemeralInstallDir; 619 620 /** 621 * Directory to which applications installed internally have their 622 * 32 bit native libraries copied. 623 */ 624 private File mAppLib32InstallDir; 625 626 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 627 // apps. 628 final File mDrmAppPrivateInstallDir; 629 630 // ---------------------------------------------------------------- 631 632 // Lock for state used when installing and doing other long running 633 // operations. Methods that must be called with this lock held have 634 // the suffix "LI". 635 final Object mInstallLock = new Object(); 636 637 // ---------------------------------------------------------------- 638 639 // Keys are String (package name), values are Package. This also serves 640 // as the lock for the global state. Methods that must be called with 641 // this lock held have the prefix "LP". 642 @GuardedBy("mPackages") 643 final ArrayMap<String, PackageParser.Package> mPackages = 644 new ArrayMap<String, PackageParser.Package>(); 645 646 final ArrayMap<String, Set<String>> mKnownCodebase = 647 new ArrayMap<String, Set<String>>(); 648 649 // Tracks available target package names -> overlay package paths. 650 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 651 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 652 653 /** 654 * Tracks new system packages [received in an OTA] that we expect to 655 * find updated user-installed versions. Keys are package name, values 656 * are package location. 657 */ 658 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 659 /** 660 * Tracks high priority intent filters for protected actions. During boot, certain 661 * filter actions are protected and should never be allowed to have a high priority 662 * intent filter for them. However, there is one, and only one exception -- the 663 * setup wizard. It must be able to define a high priority intent filter for these 664 * actions to ensure there are no escapes from the wizard. We need to delay processing 665 * of these during boot as we need to look at all of the system packages in order 666 * to know which component is the setup wizard. 667 */ 668 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 669 /** 670 * Whether or not processing protected filters should be deferred. 671 */ 672 private boolean mDeferProtectedFilters = true; 673 674 /** 675 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 676 */ 677 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 678 /** 679 * Whether or not system app permissions should be promoted from install to runtime. 680 */ 681 boolean mPromoteSystemApps; 682 683 @GuardedBy("mPackages") 684 final Settings mSettings; 685 686 /** 687 * Set of package names that are currently "frozen", which means active 688 * surgery is being done on the code/data for that package. The platform 689 * will refuse to launch frozen packages to avoid race conditions. 690 * 691 * @see PackageFreezer 692 */ 693 @GuardedBy("mPackages") 694 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 695 696 final ProtectedPackages mProtectedPackages; 697 698 boolean mFirstBoot; 699 700 // System configuration read by SystemConfig. 701 final int[] mGlobalGids; 702 final SparseArray<ArraySet<String>> mSystemPermissions; 703 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 704 705 // If mac_permissions.xml was found for seinfo labeling. 706 boolean mFoundPolicyFile; 707 708 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 709 710 public static final class SharedLibraryEntry { 711 public final String path; 712 public final String apk; 713 714 SharedLibraryEntry(String _path, String _apk) { 715 path = _path; 716 apk = _apk; 717 } 718 } 719 720 // Currently known shared libraries. 721 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 722 new ArrayMap<String, SharedLibraryEntry>(); 723 724 // All available activities, for your resolving pleasure. 725 final ActivityIntentResolver mActivities = 726 new ActivityIntentResolver(); 727 728 // All available receivers, for your resolving pleasure. 729 final ActivityIntentResolver mReceivers = 730 new ActivityIntentResolver(); 731 732 // All available services, for your resolving pleasure. 733 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 734 735 // All available providers, for your resolving pleasure. 736 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 737 738 // Mapping from provider base names (first directory in content URI codePath) 739 // to the provider information. 740 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 741 new ArrayMap<String, PackageParser.Provider>(); 742 743 // Mapping from instrumentation class names to info about them. 744 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 745 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 746 747 // Mapping from permission names to info about them. 748 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 749 new ArrayMap<String, PackageParser.PermissionGroup>(); 750 751 // Packages whose data we have transfered into another package, thus 752 // should no longer exist. 753 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 754 755 // Broadcast actions that are only available to the system. 756 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 757 758 /** List of packages waiting for verification. */ 759 final SparseArray<PackageVerificationState> mPendingVerification 760 = new SparseArray<PackageVerificationState>(); 761 762 /** Set of packages associated with each app op permission. */ 763 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 764 765 final PackageInstallerService mInstallerService; 766 767 private final PackageDexOptimizer mPackageDexOptimizer; 768 // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package 769 // is used by other apps). 770 private final DexManager mDexManager; 771 772 private AtomicInteger mNextMoveId = new AtomicInteger(); 773 private final MoveCallbacks mMoveCallbacks; 774 775 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 776 777 // Cache of users who need badging. 778 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 779 780 /** Token for keys in mPendingVerification. */ 781 private int mPendingVerificationToken = 0; 782 783 volatile boolean mSystemReady; 784 volatile boolean mSafeMode; 785 volatile boolean mHasSystemUidErrors; 786 787 ApplicationInfo mAndroidApplication; 788 final ActivityInfo mResolveActivity = new ActivityInfo(); 789 final ResolveInfo mResolveInfo = new ResolveInfo(); 790 ComponentName mResolveComponentName; 791 PackageParser.Package mPlatformPackage; 792 ComponentName mCustomResolverComponentName; 793 794 boolean mResolverReplaced = false; 795 796 private final @Nullable ComponentName mIntentFilterVerifierComponent; 797 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 798 799 private int mIntentFilterVerificationToken = 0; 800 801 /** The service connection to the ephemeral resolver */ 802 final EphemeralResolverConnection mEphemeralResolverConnection; 803 804 /** Component used to install ephemeral applications */ 805 ComponentName mEphemeralInstallerComponent; 806 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 807 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 808 809 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 810 = new SparseArray<IntentFilterVerificationState>(); 811 812 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; 813 814 // List of packages names to keep cached, even if they are uninstalled for all users 815 private List<String> mKeepUninstalledPackages; 816 817 private UserManagerInternal mUserManagerInternal; 818 819 private File mCacheDir; 820 821 private static class IFVerificationParams { 822 PackageParser.Package pkg; 823 boolean replacing; 824 int userId; 825 int verifierUid; 826 827 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 828 int _userId, int _verifierUid) { 829 pkg = _pkg; 830 replacing = _replacing; 831 userId = _userId; 832 replacing = _replacing; 833 verifierUid = _verifierUid; 834 } 835 } 836 837 private interface IntentFilterVerifier<T extends IntentFilter> { 838 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 839 T filter, String packageName); 840 void startVerifications(int userId); 841 void receiveVerificationResponse(int verificationId); 842 } 843 844 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 845 private Context mContext; 846 private ComponentName mIntentFilterVerifierComponent; 847 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 848 849 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 850 mContext = context; 851 mIntentFilterVerifierComponent = verifierComponent; 852 } 853 854 private String getDefaultScheme() { 855 return IntentFilter.SCHEME_HTTPS; 856 } 857 858 @Override 859 public void startVerifications(int userId) { 860 // Launch verifications requests 861 int count = mCurrentIntentFilterVerifications.size(); 862 for (int n=0; n<count; n++) { 863 int verificationId = mCurrentIntentFilterVerifications.get(n); 864 final IntentFilterVerificationState ivs = 865 mIntentFilterVerificationStates.get(verificationId); 866 867 String packageName = ivs.getPackageName(); 868 869 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 870 final int filterCount = filters.size(); 871 ArraySet<String> domainsSet = new ArraySet<>(); 872 for (int m=0; m<filterCount; m++) { 873 PackageParser.ActivityIntentInfo filter = filters.get(m); 874 domainsSet.addAll(filter.getHostsList()); 875 } 876 synchronized (mPackages) { 877 if (mSettings.createIntentFilterVerificationIfNeededLPw( 878 packageName, domainsSet) != null) { 879 scheduleWriteSettingsLocked(); 880 } 881 } 882 sendVerificationRequest(userId, verificationId, ivs); 883 } 884 mCurrentIntentFilterVerifications.clear(); 885 } 886 887 private void sendVerificationRequest(int userId, int verificationId, 888 IntentFilterVerificationState ivs) { 889 890 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 891 verificationIntent.putExtra( 892 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 893 verificationId); 894 verificationIntent.putExtra( 895 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 896 getDefaultScheme()); 897 verificationIntent.putExtra( 898 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 899 ivs.getHostsString()); 900 verificationIntent.putExtra( 901 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 902 ivs.getPackageName()); 903 verificationIntent.setComponent(mIntentFilterVerifierComponent); 904 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 905 906 UserHandle user = new UserHandle(userId); 907 mContext.sendBroadcastAsUser(verificationIntent, user); 908 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 909 "Sending IntentFilter verification broadcast"); 910 } 911 912 public void receiveVerificationResponse(int verificationId) { 913 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 914 915 final boolean verified = ivs.isVerified(); 916 917 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 918 final int count = filters.size(); 919 if (DEBUG_DOMAIN_VERIFICATION) { 920 Slog.i(TAG, "Received verification response " + verificationId 921 + " for " + count + " filters, verified=" + verified); 922 } 923 for (int n=0; n<count; n++) { 924 PackageParser.ActivityIntentInfo filter = filters.get(n); 925 filter.setVerified(verified); 926 927 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 928 + " verified with result:" + verified + " and hosts:" 929 + ivs.getHostsString()); 930 } 931 932 mIntentFilterVerificationStates.remove(verificationId); 933 934 final String packageName = ivs.getPackageName(); 935 IntentFilterVerificationInfo ivi = null; 936 937 synchronized (mPackages) { 938 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 939 } 940 if (ivi == null) { 941 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 942 + verificationId + " packageName:" + packageName); 943 return; 944 } 945 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 946 "Updating IntentFilterVerificationInfo for package " + packageName 947 +" verificationId:" + verificationId); 948 949 synchronized (mPackages) { 950 if (verified) { 951 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 952 } else { 953 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 954 } 955 scheduleWriteSettingsLocked(); 956 957 final int userId = ivs.getUserId(); 958 if (userId != UserHandle.USER_ALL) { 959 final int userStatus = 960 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 961 962 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 963 boolean needUpdate = false; 964 965 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 966 // already been set by the User thru the Disambiguation dialog 967 switch (userStatus) { 968 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 969 if (verified) { 970 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 971 } else { 972 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 973 } 974 needUpdate = true; 975 break; 976 977 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 978 if (verified) { 979 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 980 needUpdate = true; 981 } 982 break; 983 984 default: 985 // Nothing to do 986 } 987 988 if (needUpdate) { 989 mSettings.updateIntentFilterVerificationStatusLPw( 990 packageName, updatedStatus, userId); 991 scheduleWritePackageRestrictionsLocked(userId); 992 } 993 } 994 } 995 } 996 997 @Override 998 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 999 ActivityIntentInfo filter, String packageName) { 1000 if (!hasValidDomains(filter)) { 1001 return false; 1002 } 1003 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 1004 if (ivs == null) { 1005 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 1006 packageName); 1007 } 1008 if (DEBUG_DOMAIN_VERIFICATION) { 1009 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 1010 } 1011 ivs.addFilter(filter); 1012 return true; 1013 } 1014 1015 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 1016 int userId, int verificationId, String packageName) { 1017 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 1018 verifierUid, userId, packageName); 1019 ivs.setPendingState(); 1020 synchronized (mPackages) { 1021 mIntentFilterVerificationStates.append(verificationId, ivs); 1022 mCurrentIntentFilterVerifications.add(verificationId); 1023 } 1024 return ivs; 1025 } 1026 } 1027 1028 private static boolean hasValidDomains(ActivityIntentInfo filter) { 1029 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 1030 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 1031 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 1032 } 1033 1034 // Set of pending broadcasts for aggregating enable/disable of components. 1035 static class PendingPackageBroadcasts { 1036 // for each user id, a map of <package name -> components within that package> 1037 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 1038 1039 public PendingPackageBroadcasts() { 1040 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 1041 } 1042 1043 public ArrayList<String> get(int userId, String packageName) { 1044 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1045 return packages.get(packageName); 1046 } 1047 1048 public void put(int userId, String packageName, ArrayList<String> components) { 1049 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 1050 packages.put(packageName, components); 1051 } 1052 1053 public void remove(int userId, String packageName) { 1054 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 1055 if (packages != null) { 1056 packages.remove(packageName); 1057 } 1058 } 1059 1060 public void remove(int userId) { 1061 mUidMap.remove(userId); 1062 } 1063 1064 public int userIdCount() { 1065 return mUidMap.size(); 1066 } 1067 1068 public int userIdAt(int n) { 1069 return mUidMap.keyAt(n); 1070 } 1071 1072 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 1073 return mUidMap.get(userId); 1074 } 1075 1076 public int size() { 1077 // total number of pending broadcast entries across all userIds 1078 int num = 0; 1079 for (int i = 0; i< mUidMap.size(); i++) { 1080 num += mUidMap.valueAt(i).size(); 1081 } 1082 return num; 1083 } 1084 1085 public void clear() { 1086 mUidMap.clear(); 1087 } 1088 1089 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1090 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1091 if (map == null) { 1092 map = new ArrayMap<String, ArrayList<String>>(); 1093 mUidMap.put(userId, map); 1094 } 1095 return map; 1096 } 1097 } 1098 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1099 1100 // Service Connection to remote media container service to copy 1101 // package uri's from external media onto secure containers 1102 // or internal storage. 1103 private IMediaContainerService mContainerService = null; 1104 1105 static final int SEND_PENDING_BROADCAST = 1; 1106 static final int MCS_BOUND = 3; 1107 static final int END_COPY = 4; 1108 static final int INIT_COPY = 5; 1109 static final int MCS_UNBIND = 6; 1110 static final int START_CLEANING_PACKAGE = 7; 1111 static final int FIND_INSTALL_LOC = 8; 1112 static final int POST_INSTALL = 9; 1113 static final int MCS_RECONNECT = 10; 1114 static final int MCS_GIVE_UP = 11; 1115 static final int UPDATED_MEDIA_STATUS = 12; 1116 static final int WRITE_SETTINGS = 13; 1117 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1118 static final int PACKAGE_VERIFIED = 15; 1119 static final int CHECK_PENDING_VERIFICATION = 16; 1120 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1121 static final int INTENT_FILTER_VERIFIED = 18; 1122 static final int WRITE_PACKAGE_LIST = 19; 1123 static final int EPHEMERAL_RESOLUTION_PHASE_TWO = 20; 1124 1125 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1126 1127 // Delay time in millisecs 1128 static final int BROADCAST_DELAY = 10 * 1000; 1129 1130 static UserManagerService sUserManager; 1131 1132 // Stores a list of users whose package restrictions file needs to be updated 1133 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1134 1135 final private DefaultContainerConnection mDefContainerConn = 1136 new DefaultContainerConnection(); 1137 class DefaultContainerConnection implements ServiceConnection { 1138 public void onServiceConnected(ComponentName name, IBinder service) { 1139 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1140 final IMediaContainerService imcs = IMediaContainerService.Stub 1141 .asInterface(Binder.allowBlocking(service)); 1142 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1143 } 1144 1145 public void onServiceDisconnected(ComponentName name) { 1146 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1147 } 1148 } 1149 1150 // Recordkeeping of restore-after-install operations that are currently in flight 1151 // between the Package Manager and the Backup Manager 1152 static class PostInstallData { 1153 public InstallArgs args; 1154 public PackageInstalledInfo res; 1155 1156 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1157 args = _a; 1158 res = _r; 1159 } 1160 } 1161 1162 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1163 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1164 1165 // XML tags for backup/restore of various bits of state 1166 private static final String TAG_PREFERRED_BACKUP = "pa"; 1167 private static final String TAG_DEFAULT_APPS = "da"; 1168 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1169 1170 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1171 private static final String TAG_ALL_GRANTS = "rt-grants"; 1172 private static final String TAG_GRANT = "grant"; 1173 private static final String ATTR_PACKAGE_NAME = "pkg"; 1174 1175 private static final String TAG_PERMISSION = "perm"; 1176 private static final String ATTR_PERMISSION_NAME = "name"; 1177 private static final String ATTR_IS_GRANTED = "g"; 1178 private static final String ATTR_USER_SET = "set"; 1179 private static final String ATTR_USER_FIXED = "fixed"; 1180 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1181 1182 // System/policy permission grants are not backed up 1183 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1184 FLAG_PERMISSION_POLICY_FIXED 1185 | FLAG_PERMISSION_SYSTEM_FIXED 1186 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1187 1188 // And we back up these user-adjusted states 1189 private static final int USER_RUNTIME_GRANT_MASK = 1190 FLAG_PERMISSION_USER_SET 1191 | FLAG_PERMISSION_USER_FIXED 1192 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1193 1194 final @Nullable String mRequiredVerifierPackage; 1195 final @NonNull String mRequiredInstallerPackage; 1196 final @NonNull String mRequiredUninstallerPackage; 1197 final @Nullable String mSetupWizardPackage; 1198 final @Nullable String mStorageManagerPackage; 1199 final @NonNull String mServicesSystemSharedLibraryPackageName; 1200 final @NonNull String mSharedSystemSharedLibraryPackageName; 1201 1202 final boolean mPermissionReviewRequired; 1203 1204 private final PackageUsage mPackageUsage = new PackageUsage(); 1205 private final CompilerStats mCompilerStats = new CompilerStats(); 1206 1207 class PackageHandler extends Handler { 1208 private boolean mBound = false; 1209 final ArrayList<HandlerParams> mPendingInstalls = 1210 new ArrayList<HandlerParams>(); 1211 1212 private boolean connectToService() { 1213 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1214 " DefaultContainerService"); 1215 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1216 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1217 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1218 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1219 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1220 mBound = true; 1221 return true; 1222 } 1223 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1224 return false; 1225 } 1226 1227 private void disconnectService() { 1228 mContainerService = null; 1229 mBound = false; 1230 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1231 mContext.unbindService(mDefContainerConn); 1232 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1233 } 1234 1235 PackageHandler(Looper looper) { 1236 super(looper); 1237 } 1238 1239 public void handleMessage(Message msg) { 1240 try { 1241 doHandleMessage(msg); 1242 } finally { 1243 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1244 } 1245 } 1246 1247 void doHandleMessage(Message msg) { 1248 switch (msg.what) { 1249 case INIT_COPY: { 1250 HandlerParams params = (HandlerParams) msg.obj; 1251 int idx = mPendingInstalls.size(); 1252 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1253 // If a bind was already initiated we dont really 1254 // need to do anything. The pending install 1255 // will be processed later on. 1256 if (!mBound) { 1257 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1258 System.identityHashCode(mHandler)); 1259 // If this is the only one pending we might 1260 // have to bind to the service again. 1261 if (!connectToService()) { 1262 Slog.e(TAG, "Failed to bind to media container service"); 1263 params.serviceError(); 1264 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1265 System.identityHashCode(mHandler)); 1266 if (params.traceMethod != null) { 1267 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1268 params.traceCookie); 1269 } 1270 return; 1271 } else { 1272 // Once we bind to the service, the first 1273 // pending request will be processed. 1274 mPendingInstalls.add(idx, params); 1275 } 1276 } else { 1277 mPendingInstalls.add(idx, params); 1278 // Already bound to the service. Just make 1279 // sure we trigger off processing the first request. 1280 if (idx == 0) { 1281 mHandler.sendEmptyMessage(MCS_BOUND); 1282 } 1283 } 1284 break; 1285 } 1286 case MCS_BOUND: { 1287 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1288 if (msg.obj != null) { 1289 mContainerService = (IMediaContainerService) msg.obj; 1290 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1291 System.identityHashCode(mHandler)); 1292 } 1293 if (mContainerService == null) { 1294 if (!mBound) { 1295 // Something seriously wrong since we are not bound and we are not 1296 // waiting for connection. Bail out. 1297 Slog.e(TAG, "Cannot bind to media container service"); 1298 for (HandlerParams params : mPendingInstalls) { 1299 // Indicate service bind error 1300 params.serviceError(); 1301 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1302 System.identityHashCode(params)); 1303 if (params.traceMethod != null) { 1304 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1305 params.traceMethod, params.traceCookie); 1306 } 1307 return; 1308 } 1309 mPendingInstalls.clear(); 1310 } else { 1311 Slog.w(TAG, "Waiting to connect to media container service"); 1312 } 1313 } else if (mPendingInstalls.size() > 0) { 1314 HandlerParams params = mPendingInstalls.get(0); 1315 if (params != null) { 1316 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1317 System.identityHashCode(params)); 1318 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1319 if (params.startCopy()) { 1320 // We are done... look for more work or to 1321 // go idle. 1322 if (DEBUG_SD_INSTALL) Log.i(TAG, 1323 "Checking for more work or unbind..."); 1324 // Delete pending install 1325 if (mPendingInstalls.size() > 0) { 1326 mPendingInstalls.remove(0); 1327 } 1328 if (mPendingInstalls.size() == 0) { 1329 if (mBound) { 1330 if (DEBUG_SD_INSTALL) Log.i(TAG, 1331 "Posting delayed MCS_UNBIND"); 1332 removeMessages(MCS_UNBIND); 1333 Message ubmsg = obtainMessage(MCS_UNBIND); 1334 // Unbind after a little delay, to avoid 1335 // continual thrashing. 1336 sendMessageDelayed(ubmsg, 10000); 1337 } 1338 } else { 1339 // There are more pending requests in queue. 1340 // Just post MCS_BOUND message to trigger processing 1341 // of next pending install. 1342 if (DEBUG_SD_INSTALL) Log.i(TAG, 1343 "Posting MCS_BOUND for next work"); 1344 mHandler.sendEmptyMessage(MCS_BOUND); 1345 } 1346 } 1347 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1348 } 1349 } else { 1350 // Should never happen ideally. 1351 Slog.w(TAG, "Empty queue"); 1352 } 1353 break; 1354 } 1355 case MCS_RECONNECT: { 1356 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1357 if (mPendingInstalls.size() > 0) { 1358 if (mBound) { 1359 disconnectService(); 1360 } 1361 if (!connectToService()) { 1362 Slog.e(TAG, "Failed to bind to media container service"); 1363 for (HandlerParams params : mPendingInstalls) { 1364 // Indicate service bind error 1365 params.serviceError(); 1366 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1367 System.identityHashCode(params)); 1368 } 1369 mPendingInstalls.clear(); 1370 } 1371 } 1372 break; 1373 } 1374 case MCS_UNBIND: { 1375 // If there is no actual work left, then time to unbind. 1376 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1377 1378 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1379 if (mBound) { 1380 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1381 1382 disconnectService(); 1383 } 1384 } else if (mPendingInstalls.size() > 0) { 1385 // There are more pending requests in queue. 1386 // Just post MCS_BOUND message to trigger processing 1387 // of next pending install. 1388 mHandler.sendEmptyMessage(MCS_BOUND); 1389 } 1390 1391 break; 1392 } 1393 case MCS_GIVE_UP: { 1394 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1395 HandlerParams params = mPendingInstalls.remove(0); 1396 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1397 System.identityHashCode(params)); 1398 break; 1399 } 1400 case SEND_PENDING_BROADCAST: { 1401 String packages[]; 1402 ArrayList<String> components[]; 1403 int size = 0; 1404 int uids[]; 1405 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1406 synchronized (mPackages) { 1407 if (mPendingBroadcasts == null) { 1408 return; 1409 } 1410 size = mPendingBroadcasts.size(); 1411 if (size <= 0) { 1412 // Nothing to be done. Just return 1413 return; 1414 } 1415 packages = new String[size]; 1416 components = new ArrayList[size]; 1417 uids = new int[size]; 1418 int i = 0; // filling out the above arrays 1419 1420 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1421 int packageUserId = mPendingBroadcasts.userIdAt(n); 1422 Iterator<Map.Entry<String, ArrayList<String>>> it 1423 = mPendingBroadcasts.packagesForUserId(packageUserId) 1424 .entrySet().iterator(); 1425 while (it.hasNext() && i < size) { 1426 Map.Entry<String, ArrayList<String>> ent = it.next(); 1427 packages[i] = ent.getKey(); 1428 components[i] = ent.getValue(); 1429 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1430 uids[i] = (ps != null) 1431 ? UserHandle.getUid(packageUserId, ps.appId) 1432 : -1; 1433 i++; 1434 } 1435 } 1436 size = i; 1437 mPendingBroadcasts.clear(); 1438 } 1439 // Send broadcasts 1440 for (int i = 0; i < size; i++) { 1441 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1442 } 1443 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1444 break; 1445 } 1446 case START_CLEANING_PACKAGE: { 1447 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1448 final String packageName = (String)msg.obj; 1449 final int userId = msg.arg1; 1450 final boolean andCode = msg.arg2 != 0; 1451 synchronized (mPackages) { 1452 if (userId == UserHandle.USER_ALL) { 1453 int[] users = sUserManager.getUserIds(); 1454 for (int user : users) { 1455 mSettings.addPackageToCleanLPw( 1456 new PackageCleanItem(user, packageName, andCode)); 1457 } 1458 } else { 1459 mSettings.addPackageToCleanLPw( 1460 new PackageCleanItem(userId, packageName, andCode)); 1461 } 1462 } 1463 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1464 startCleaningPackages(); 1465 } break; 1466 case POST_INSTALL: { 1467 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1468 1469 PostInstallData data = mRunningInstalls.get(msg.arg1); 1470 final boolean didRestore = (msg.arg2 != 0); 1471 mRunningInstalls.delete(msg.arg1); 1472 1473 if (data != null) { 1474 InstallArgs args = data.args; 1475 PackageInstalledInfo parentRes = data.res; 1476 1477 final boolean grantPermissions = (args.installFlags 1478 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1479 final boolean killApp = (args.installFlags 1480 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1481 final String[] grantedPermissions = args.installGrantPermissions; 1482 1483 // Handle the parent package 1484 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1485 grantedPermissions, didRestore, args.installerPackageName, 1486 args.observer); 1487 1488 // Handle the child packages 1489 final int childCount = (parentRes.addedChildPackages != null) 1490 ? parentRes.addedChildPackages.size() : 0; 1491 for (int i = 0; i < childCount; i++) { 1492 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1493 handlePackagePostInstall(childRes, grantPermissions, killApp, 1494 grantedPermissions, false, args.installerPackageName, 1495 args.observer); 1496 } 1497 1498 // Log tracing if needed 1499 if (args.traceMethod != null) { 1500 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1501 args.traceCookie); 1502 } 1503 } else { 1504 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1505 } 1506 1507 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1508 } break; 1509 case UPDATED_MEDIA_STATUS: { 1510 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1511 boolean reportStatus = msg.arg1 == 1; 1512 boolean doGc = msg.arg2 == 1; 1513 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1514 if (doGc) { 1515 // Force a gc to clear up stale containers. 1516 Runtime.getRuntime().gc(); 1517 } 1518 if (msg.obj != null) { 1519 @SuppressWarnings("unchecked") 1520 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1521 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1522 // Unload containers 1523 unloadAllContainers(args); 1524 } 1525 if (reportStatus) { 1526 try { 1527 if (DEBUG_SD_INSTALL) Log.i(TAG, 1528 "Invoking StorageManagerService call back"); 1529 PackageHelper.getStorageManager().finishMediaUpdate(); 1530 } catch (RemoteException e) { 1531 Log.e(TAG, "StorageManagerService not running?"); 1532 } 1533 } 1534 } break; 1535 case WRITE_SETTINGS: { 1536 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1537 synchronized (mPackages) { 1538 removeMessages(WRITE_SETTINGS); 1539 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1540 mSettings.writeLPr(); 1541 mDirtyUsers.clear(); 1542 } 1543 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1544 } break; 1545 case WRITE_PACKAGE_RESTRICTIONS: { 1546 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1547 synchronized (mPackages) { 1548 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1549 for (int userId : mDirtyUsers) { 1550 mSettings.writePackageRestrictionsLPr(userId); 1551 } 1552 mDirtyUsers.clear(); 1553 } 1554 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1555 } break; 1556 case WRITE_PACKAGE_LIST: { 1557 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1558 synchronized (mPackages) { 1559 removeMessages(WRITE_PACKAGE_LIST); 1560 mSettings.writePackageListLPr(msg.arg1); 1561 } 1562 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1563 } break; 1564 case CHECK_PENDING_VERIFICATION: { 1565 final int verificationId = msg.arg1; 1566 final PackageVerificationState state = mPendingVerification.get(verificationId); 1567 1568 if ((state != null) && !state.timeoutExtended()) { 1569 final InstallArgs args = state.getInstallArgs(); 1570 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1571 1572 Slog.i(TAG, "Verification timed out for " + originUri); 1573 mPendingVerification.remove(verificationId); 1574 1575 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1576 1577 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1578 Slog.i(TAG, "Continuing with installation of " + originUri); 1579 state.setVerifierResponse(Binder.getCallingUid(), 1580 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1581 broadcastPackageVerified(verificationId, originUri, 1582 PackageManager.VERIFICATION_ALLOW, 1583 state.getInstallArgs().getUser()); 1584 try { 1585 ret = args.copyApk(mContainerService, true); 1586 } catch (RemoteException e) { 1587 Slog.e(TAG, "Could not contact the ContainerService"); 1588 } 1589 } else { 1590 broadcastPackageVerified(verificationId, originUri, 1591 PackageManager.VERIFICATION_REJECT, 1592 state.getInstallArgs().getUser()); 1593 } 1594 1595 Trace.asyncTraceEnd( 1596 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1597 1598 processPendingInstall(args, ret); 1599 mHandler.sendEmptyMessage(MCS_UNBIND); 1600 } 1601 break; 1602 } 1603 case PACKAGE_VERIFIED: { 1604 final int verificationId = msg.arg1; 1605 1606 final PackageVerificationState state = mPendingVerification.get(verificationId); 1607 if (state == null) { 1608 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1609 break; 1610 } 1611 1612 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1613 1614 state.setVerifierResponse(response.callerUid, response.code); 1615 1616 if (state.isVerificationComplete()) { 1617 mPendingVerification.remove(verificationId); 1618 1619 final InstallArgs args = state.getInstallArgs(); 1620 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1621 1622 int ret; 1623 if (state.isInstallAllowed()) { 1624 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1625 broadcastPackageVerified(verificationId, originUri, 1626 response.code, state.getInstallArgs().getUser()); 1627 try { 1628 ret = args.copyApk(mContainerService, true); 1629 } catch (RemoteException e) { 1630 Slog.e(TAG, "Could not contact the ContainerService"); 1631 } 1632 } else { 1633 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1634 } 1635 1636 Trace.asyncTraceEnd( 1637 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1638 1639 processPendingInstall(args, ret); 1640 mHandler.sendEmptyMessage(MCS_UNBIND); 1641 } 1642 1643 break; 1644 } 1645 case START_INTENT_FILTER_VERIFICATIONS: { 1646 IFVerificationParams params = (IFVerificationParams) msg.obj; 1647 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1648 params.replacing, params.pkg); 1649 break; 1650 } 1651 case INTENT_FILTER_VERIFIED: { 1652 final int verificationId = msg.arg1; 1653 1654 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1655 verificationId); 1656 if (state == null) { 1657 Slog.w(TAG, "Invalid IntentFilter verification token " 1658 + verificationId + " received"); 1659 break; 1660 } 1661 1662 final int userId = state.getUserId(); 1663 1664 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1665 "Processing IntentFilter verification with token:" 1666 + verificationId + " and userId:" + userId); 1667 1668 final IntentFilterVerificationResponse response = 1669 (IntentFilterVerificationResponse) msg.obj; 1670 1671 state.setVerifierResponse(response.callerUid, response.code); 1672 1673 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1674 "IntentFilter verification with token:" + verificationId 1675 + " and userId:" + userId 1676 + " is settings verifier response with response code:" 1677 + response.code); 1678 1679 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1680 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1681 + response.getFailedDomainsString()); 1682 } 1683 1684 if (state.isVerificationComplete()) { 1685 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1686 } else { 1687 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1688 "IntentFilter verification with token:" + verificationId 1689 + " was not said to be complete"); 1690 } 1691 1692 break; 1693 } 1694 case EPHEMERAL_RESOLUTION_PHASE_TWO: { 1695 EphemeralResolver.doEphemeralResolutionPhaseTwo(mContext, 1696 mEphemeralResolverConnection, 1697 (EphemeralRequest) msg.obj, 1698 mEphemeralInstallerActivity, 1699 mHandler); 1700 } 1701 } 1702 } 1703 } 1704 1705 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1706 boolean killApp, String[] grantedPermissions, 1707 boolean launchedForRestore, String installerPackage, 1708 IPackageInstallObserver2 installObserver) { 1709 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1710 // Send the removed broadcasts 1711 if (res.removedInfo != null) { 1712 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1713 } 1714 1715 // Now that we successfully installed the package, grant runtime 1716 // permissions if requested before broadcasting the install. 1717 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1718 >= Build.VERSION_CODES.M) { 1719 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1720 } 1721 1722 final boolean update = res.removedInfo != null 1723 && res.removedInfo.removedPackage != null; 1724 1725 // If this is the first time we have child packages for a disabled privileged 1726 // app that had no children, we grant requested runtime permissions to the new 1727 // children if the parent on the system image had them already granted. 1728 if (res.pkg.parentPackage != null) { 1729 synchronized (mPackages) { 1730 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1731 } 1732 } 1733 1734 synchronized (mPackages) { 1735 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1736 } 1737 1738 final String packageName = res.pkg.applicationInfo.packageName; 1739 1740 // Determine the set of users who are adding this package for 1741 // the first time vs. those who are seeing an update. 1742 int[] firstUsers = EMPTY_INT_ARRAY; 1743 int[] updateUsers = EMPTY_INT_ARRAY; 1744 if (res.origUsers == null || res.origUsers.length == 0) { 1745 firstUsers = res.newUsers; 1746 } else { 1747 for (int newUser : res.newUsers) { 1748 boolean isNew = true; 1749 for (int origUser : res.origUsers) { 1750 if (origUser == newUser) { 1751 isNew = false; 1752 break; 1753 } 1754 } 1755 if (isNew) { 1756 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1757 } else { 1758 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1759 } 1760 } 1761 } 1762 1763 // Send installed broadcasts if the install/update is not ephemeral 1764 if (!isEphemeral(res.pkg)) { 1765 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1766 1767 // Send added for users that see the package for the first time 1768 // sendPackageAddedForNewUsers also deals with system apps 1769 int appId = UserHandle.getAppId(res.uid); 1770 boolean isSystem = res.pkg.applicationInfo.isSystemApp(); 1771 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers); 1772 1773 // Send added for users that don't see the package for the first time 1774 Bundle extras = new Bundle(1); 1775 extras.putInt(Intent.EXTRA_UID, res.uid); 1776 if (update) { 1777 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1778 } 1779 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1780 extras, 0 /*flags*/, null /*targetPackage*/, 1781 null /*finishedReceiver*/, updateUsers); 1782 1783 // Send replaced for users that don't see the package for the first time 1784 if (update) { 1785 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1786 packageName, extras, 0 /*flags*/, 1787 null /*targetPackage*/, null /*finishedReceiver*/, 1788 updateUsers); 1789 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1790 null /*package*/, null /*extras*/, 0 /*flags*/, 1791 packageName /*targetPackage*/, 1792 null /*finishedReceiver*/, updateUsers); 1793 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1794 // First-install and we did a restore, so we're responsible for the 1795 // first-launch broadcast. 1796 if (DEBUG_BACKUP) { 1797 Slog.i(TAG, "Post-restore of " + packageName 1798 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1799 } 1800 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1801 } 1802 1803 // Send broadcast package appeared if forward locked/external for all users 1804 // treat asec-hosted packages like removable media on upgrade 1805 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1806 if (DEBUG_INSTALL) { 1807 Slog.i(TAG, "upgrading pkg " + res.pkg 1808 + " is ASEC-hosted -> AVAILABLE"); 1809 } 1810 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1811 ArrayList<String> pkgList = new ArrayList<>(1); 1812 pkgList.add(packageName); 1813 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1814 } 1815 } 1816 1817 // Work that needs to happen on first install within each user 1818 if (firstUsers != null && firstUsers.length > 0) { 1819 synchronized (mPackages) { 1820 for (int userId : firstUsers) { 1821 // If this app is a browser and it's newly-installed for some 1822 // users, clear any default-browser state in those users. The 1823 // app's nature doesn't depend on the user, so we can just check 1824 // its browser nature in any user and generalize. 1825 if (packageIsBrowser(packageName, userId)) { 1826 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1827 } 1828 1829 // We may also need to apply pending (restored) runtime 1830 // permission grants within these users. 1831 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1832 } 1833 } 1834 } 1835 1836 // Log current value of "unknown sources" setting 1837 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1838 getUnknownSourcesSettings()); 1839 1840 // Force a gc to clear up things 1841 Runtime.getRuntime().gc(); 1842 1843 // Remove the replaced package's older resources safely now 1844 // We delete after a gc for applications on sdcard. 1845 if (res.removedInfo != null && res.removedInfo.args != null) { 1846 synchronized (mInstallLock) { 1847 res.removedInfo.args.doPostDeleteLI(true); 1848 } 1849 } 1850 } 1851 1852 // If someone is watching installs - notify them 1853 if (installObserver != null) { 1854 try { 1855 Bundle extras = extrasForInstallResult(res); 1856 installObserver.onPackageInstalled(res.name, res.returnCode, 1857 res.returnMsg, extras); 1858 } catch (RemoteException e) { 1859 Slog.i(TAG, "Observer no longer exists."); 1860 } 1861 } 1862 } 1863 1864 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1865 PackageParser.Package pkg) { 1866 if (pkg.parentPackage == null) { 1867 return; 1868 } 1869 if (pkg.requestedPermissions == null) { 1870 return; 1871 } 1872 final PackageSetting disabledSysParentPs = mSettings 1873 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1874 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1875 || !disabledSysParentPs.isPrivileged() 1876 || (disabledSysParentPs.childPackageNames != null 1877 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1878 return; 1879 } 1880 final int[] allUserIds = sUserManager.getUserIds(); 1881 final int permCount = pkg.requestedPermissions.size(); 1882 for (int i = 0; i < permCount; i++) { 1883 String permission = pkg.requestedPermissions.get(i); 1884 BasePermission bp = mSettings.mPermissions.get(permission); 1885 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1886 continue; 1887 } 1888 for (int userId : allUserIds) { 1889 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1890 permission, userId)) { 1891 grantRuntimePermission(pkg.packageName, permission, userId); 1892 } 1893 } 1894 } 1895 } 1896 1897 private StorageEventListener mStorageListener = new StorageEventListener() { 1898 @Override 1899 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1900 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1901 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1902 final String volumeUuid = vol.getFsUuid(); 1903 1904 // Clean up any users or apps that were removed or recreated 1905 // while this volume was missing 1906 reconcileUsers(volumeUuid); 1907 reconcileApps(volumeUuid); 1908 1909 // Clean up any install sessions that expired or were 1910 // cancelled while this volume was missing 1911 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1912 1913 loadPrivatePackages(vol); 1914 1915 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1916 unloadPrivatePackages(vol); 1917 } 1918 } 1919 1920 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1921 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1922 updateExternalMediaStatus(true, false); 1923 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1924 updateExternalMediaStatus(false, false); 1925 } 1926 } 1927 } 1928 1929 @Override 1930 public void onVolumeForgotten(String fsUuid) { 1931 if (TextUtils.isEmpty(fsUuid)) { 1932 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1933 return; 1934 } 1935 1936 // Remove any apps installed on the forgotten volume 1937 synchronized (mPackages) { 1938 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1939 for (PackageSetting ps : packages) { 1940 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1941 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1942 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1943 1944 // Try very hard to release any references to this package 1945 // so we don't risk the system server being killed due to 1946 // open FDs 1947 AttributeCache.instance().removePackage(ps.name); 1948 } 1949 1950 mSettings.onVolumeForgotten(fsUuid); 1951 mSettings.writeLPr(); 1952 } 1953 } 1954 }; 1955 1956 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1957 String[] grantedPermissions) { 1958 for (int userId : userIds) { 1959 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1960 } 1961 1962 // We could have touched GID membership, so flush out packages.list 1963 synchronized (mPackages) { 1964 mSettings.writePackageListLPr(); 1965 } 1966 } 1967 1968 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1969 String[] grantedPermissions) { 1970 SettingBase sb = (SettingBase) pkg.mExtras; 1971 if (sb == null) { 1972 return; 1973 } 1974 1975 PermissionsState permissionsState = sb.getPermissionsState(); 1976 1977 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1978 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1979 1980 for (String permission : pkg.requestedPermissions) { 1981 final BasePermission bp; 1982 synchronized (mPackages) { 1983 bp = mSettings.mPermissions.get(permission); 1984 } 1985 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1986 && (grantedPermissions == null 1987 || ArrayUtils.contains(grantedPermissions, permission))) { 1988 final int flags = permissionsState.getPermissionFlags(permission, userId); 1989 // Installer cannot change immutable permissions. 1990 if ((flags & immutableFlags) == 0) { 1991 grantRuntimePermission(pkg.packageName, permission, userId); 1992 } 1993 } 1994 } 1995 } 1996 1997 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1998 Bundle extras = null; 1999 switch (res.returnCode) { 2000 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 2001 extras = new Bundle(); 2002 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 2003 res.origPermission); 2004 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 2005 res.origPackage); 2006 break; 2007 } 2008 case PackageManager.INSTALL_SUCCEEDED: { 2009 extras = new Bundle(); 2010 extras.putBoolean(Intent.EXTRA_REPLACING, 2011 res.removedInfo != null && res.removedInfo.removedPackage != null); 2012 break; 2013 } 2014 } 2015 return extras; 2016 } 2017 2018 void scheduleWriteSettingsLocked() { 2019 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 2020 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 2021 } 2022 } 2023 2024 void scheduleWritePackageListLocked(int userId) { 2025 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 2026 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 2027 msg.arg1 = userId; 2028 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 2029 } 2030 } 2031 2032 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 2033 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 2034 scheduleWritePackageRestrictionsLocked(userId); 2035 } 2036 2037 void scheduleWritePackageRestrictionsLocked(int userId) { 2038 final int[] userIds = (userId == UserHandle.USER_ALL) 2039 ? sUserManager.getUserIds() : new int[]{userId}; 2040 for (int nextUserId : userIds) { 2041 if (!sUserManager.exists(nextUserId)) return; 2042 mDirtyUsers.add(nextUserId); 2043 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 2044 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 2045 } 2046 } 2047 } 2048 2049 public static PackageManagerService main(Context context, Installer installer, 2050 boolean factoryTest, boolean onlyCore) { 2051 // Self-check for initial settings. 2052 PackageManagerServiceCompilerMapping.checkProperties(); 2053 2054 PackageManagerService m = new PackageManagerService(context, installer, 2055 factoryTest, onlyCore); 2056 m.enableSystemUserPackages(); 2057 ServiceManager.addService("package", m); 2058 return m; 2059 } 2060 2061 private void enableSystemUserPackages() { 2062 if (!UserManager.isSplitSystemUser()) { 2063 return; 2064 } 2065 // For system user, enable apps based on the following conditions: 2066 // - app is whitelisted or belong to one of these groups: 2067 // -- system app which has no launcher icons 2068 // -- system app which has INTERACT_ACROSS_USERS permission 2069 // -- system IME app 2070 // - app is not in the blacklist 2071 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 2072 Set<String> enableApps = new ArraySet<>(); 2073 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 2074 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 2075 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 2076 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2077 enableApps.addAll(wlApps); 2078 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2079 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2080 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2081 enableApps.removeAll(blApps); 2082 Log.i(TAG, "Applications installed for system user: " + enableApps); 2083 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2084 UserHandle.SYSTEM); 2085 final int allAppsSize = allAps.size(); 2086 synchronized (mPackages) { 2087 for (int i = 0; i < allAppsSize; i++) { 2088 String pName = allAps.get(i); 2089 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2090 // Should not happen, but we shouldn't be failing if it does 2091 if (pkgSetting == null) { 2092 continue; 2093 } 2094 boolean install = enableApps.contains(pName); 2095 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2096 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2097 + " for system user"); 2098 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2099 } 2100 } 2101 } 2102 } 2103 2104 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2105 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2106 Context.DISPLAY_SERVICE); 2107 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2108 } 2109 2110 /** 2111 * Requests that files preopted on a secondary system partition be copied to the data partition 2112 * if possible. Note that the actual copying of the files is accomplished by init for security 2113 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2114 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2115 */ 2116 private static void requestCopyPreoptedFiles() { 2117 final int WAIT_TIME_MS = 100; 2118 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2119 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2120 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2121 // We will wait for up to 100 seconds. 2122 final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000; 2123 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2124 try { 2125 Thread.sleep(WAIT_TIME_MS); 2126 } catch (InterruptedException e) { 2127 // Do nothing 2128 } 2129 if (SystemClock.uptimeMillis() > timeEnd) { 2130 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2131 Slog.wtf(TAG, "cppreopt did not finish!"); 2132 break; 2133 } 2134 } 2135 } 2136 } 2137 2138 public PackageManagerService(Context context, Installer installer, 2139 boolean factoryTest, boolean onlyCore) { 2140 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager"); 2141 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2142 SystemClock.uptimeMillis()); 2143 2144 if (mSdkVersion <= 0) { 2145 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2146 } 2147 2148 mContext = context; 2149 2150 mPermissionReviewRequired = context.getResources().getBoolean( 2151 R.bool.config_permissionReviewRequired); 2152 2153 mFactoryTest = factoryTest; 2154 mOnlyCore = onlyCore; 2155 mMetrics = new DisplayMetrics(); 2156 mSettings = new Settings(mPackages); 2157 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2158 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2159 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2160 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2161 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2162 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2163 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2164 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2165 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2166 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2167 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2168 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2169 2170 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2171 if (separateProcesses != null && separateProcesses.length() > 0) { 2172 if ("*".equals(separateProcesses)) { 2173 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2174 mSeparateProcesses = null; 2175 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2176 } else { 2177 mDefParseFlags = 0; 2178 mSeparateProcesses = separateProcesses.split(","); 2179 Slog.w(TAG, "Running with debug.separate_processes: " 2180 + separateProcesses); 2181 } 2182 } else { 2183 mDefParseFlags = 0; 2184 mSeparateProcesses = null; 2185 } 2186 2187 mInstaller = installer; 2188 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2189 "*dexopt*"); 2190 mDexManager = new DexManager(); 2191 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2192 2193 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2194 FgThread.get().getLooper()); 2195 2196 getDefaultDisplayMetrics(context, mMetrics); 2197 2198 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config"); 2199 SystemConfig systemConfig = SystemConfig.getInstance(); 2200 mGlobalGids = systemConfig.getGlobalGids(); 2201 mSystemPermissions = systemConfig.getSystemPermissions(); 2202 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2203 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2204 2205 mProtectedPackages = new ProtectedPackages(mContext); 2206 2207 synchronized (mInstallLock) { 2208 // writer 2209 synchronized (mPackages) { 2210 mHandlerThread = new ServiceThread(TAG, 2211 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2212 mHandlerThread.start(); 2213 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2214 mProcessLoggingHandler = new ProcessLoggingHandler(); 2215 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2216 2217 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 2218 2219 File dataDir = Environment.getDataDirectory(); 2220 mAppInstallDir = new File(dataDir, "app"); 2221 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2222 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2223 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2224 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2225 2226 sUserManager = new UserManagerService(context, this, mPackages); 2227 2228 // Propagate permission configuration in to package manager. 2229 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2230 = systemConfig.getPermissions(); 2231 for (int i=0; i<permConfig.size(); i++) { 2232 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2233 BasePermission bp = mSettings.mPermissions.get(perm.name); 2234 if (bp == null) { 2235 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2236 mSettings.mPermissions.put(perm.name, bp); 2237 } 2238 if (perm.gids != null) { 2239 bp.setGids(perm.gids, perm.perUser); 2240 } 2241 } 2242 2243 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2244 for (int i=0; i<libConfig.size(); i++) { 2245 mSharedLibraries.put(libConfig.keyAt(i), 2246 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2247 } 2248 2249 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2250 2251 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings"); 2252 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2253 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2254 2255 // Clean up orphaned packages for which the code path doesn't exist 2256 // and they are an update to a system app - caused by bug/32321269 2257 final int packageSettingCount = mSettings.mPackages.size(); 2258 for (int i = packageSettingCount - 1; i >= 0; i--) { 2259 PackageSetting ps = mSettings.mPackages.valueAt(i); 2260 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists()) 2261 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) { 2262 mSettings.mPackages.removeAt(i); 2263 mSettings.enableSystemPackageLPw(ps.name); 2264 } 2265 } 2266 2267 if (mFirstBoot) { 2268 requestCopyPreoptedFiles(); 2269 } 2270 2271 String customResolverActivity = Resources.getSystem().getString( 2272 R.string.config_customResolverActivity); 2273 if (TextUtils.isEmpty(customResolverActivity)) { 2274 customResolverActivity = null; 2275 } else { 2276 mCustomResolverComponentName = ComponentName.unflattenFromString( 2277 customResolverActivity); 2278 } 2279 2280 long startTime = SystemClock.uptimeMillis(); 2281 2282 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2283 startTime); 2284 2285 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2286 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2287 2288 if (bootClassPath == null) { 2289 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2290 } 2291 2292 if (systemServerClassPath == null) { 2293 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2294 } 2295 2296 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2297 final String[] dexCodeInstructionSets = 2298 getDexCodeInstructionSets( 2299 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2300 2301 /** 2302 * Ensure all external libraries have had dexopt run on them. 2303 */ 2304 if (mSharedLibraries.size() > 0) { 2305 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 2306 // NOTE: For now, we're compiling these system "shared libraries" 2307 // (and framework jars) into all available architectures. It's possible 2308 // to compile them only when we come across an app that uses them (there's 2309 // already logic for that in scanPackageLI) but that adds some complexity. 2310 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2311 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2312 final String lib = libEntry.path; 2313 if (lib == null) { 2314 continue; 2315 } 2316 2317 try { 2318 // Shared libraries do not have profiles so we perform a full 2319 // AOT compilation (if needed). 2320 int dexoptNeeded = DexFile.getDexOptNeeded( 2321 lib, dexCodeInstructionSet, 2322 getCompilerFilterForReason(REASON_SHARED_APK), 2323 false /* newProfile */); 2324 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2325 mInstaller.dexopt(lib, Process.SYSTEM_UID, "*", 2326 dexCodeInstructionSet, dexoptNeeded, null, 2327 DEXOPT_PUBLIC, 2328 getCompilerFilterForReason(REASON_SHARED_APK), 2329 StorageManager.UUID_PRIVATE_INTERNAL, 2330 SKIP_SHARED_LIBRARY_CHECK); 2331 } 2332 } catch (FileNotFoundException e) { 2333 Slog.w(TAG, "Library not found: " + lib); 2334 } catch (IOException | InstallerException e) { 2335 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2336 + e.getMessage()); 2337 } 2338 } 2339 } 2340 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2341 } 2342 2343 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2344 2345 final VersionInfo ver = mSettings.getInternalVersion(); 2346 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2347 2348 // when upgrading from pre-M, promote system app permissions from install to runtime 2349 mPromoteSystemApps = 2350 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2351 2352 // When upgrading from pre-N, we need to handle package extraction like first boot, 2353 // as there is no profiling data available. 2354 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2355 2356 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1; 2357 2358 // save off the names of pre-existing system packages prior to scanning; we don't 2359 // want to automatically grant runtime permissions for new system apps 2360 if (mPromoteSystemApps) { 2361 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2362 while (pkgSettingIter.hasNext()) { 2363 PackageSetting ps = pkgSettingIter.next(); 2364 if (isSystemApp(ps)) { 2365 mExistingSystemPackages.add(ps.name); 2366 } 2367 } 2368 } 2369 2370 mCacheDir = preparePackageParserCache(mIsUpgrade); 2371 2372 // Set flag to monitor and not change apk file paths when 2373 // scanning install directories. 2374 int scanFlags = SCAN_BOOTING | SCAN_INITIAL; 2375 2376 if (mIsUpgrade || mFirstBoot) { 2377 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE; 2378 } 2379 2380 // Collect vendor overlay packages. (Do this before scanning any apps.) 2381 // For security and version matching reason, only consider 2382 // overlay packages if they reside in the right directory. 2383 String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PERSIST_PROPERTY); 2384 if (overlayThemeDir.isEmpty()) { 2385 overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY); 2386 } 2387 if (!overlayThemeDir.isEmpty()) { 2388 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags 2389 | PackageParser.PARSE_IS_SYSTEM 2390 | PackageParser.PARSE_IS_SYSTEM_DIR 2391 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2392 } 2393 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags 2394 | PackageParser.PARSE_IS_SYSTEM 2395 | PackageParser.PARSE_IS_SYSTEM_DIR 2396 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2397 2398 // Find base frameworks (resource packages without code). 2399 scanDirTracedLI(frameworkDir, mDefParseFlags 2400 | PackageParser.PARSE_IS_SYSTEM 2401 | PackageParser.PARSE_IS_SYSTEM_DIR 2402 | PackageParser.PARSE_IS_PRIVILEGED, 2403 scanFlags | SCAN_NO_DEX, 0); 2404 2405 // Collected privileged system packages. 2406 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2407 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2408 | PackageParser.PARSE_IS_SYSTEM 2409 | PackageParser.PARSE_IS_SYSTEM_DIR 2410 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2411 2412 // Collect ordinary system packages. 2413 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2414 scanDirTracedLI(systemAppDir, mDefParseFlags 2415 | PackageParser.PARSE_IS_SYSTEM 2416 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2417 2418 // Collect all vendor packages. 2419 File vendorAppDir = new File("/vendor/app"); 2420 try { 2421 vendorAppDir = vendorAppDir.getCanonicalFile(); 2422 } catch (IOException e) { 2423 // failed to look up canonical path, continue with original one 2424 } 2425 scanDirTracedLI(vendorAppDir, mDefParseFlags 2426 | PackageParser.PARSE_IS_SYSTEM 2427 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2428 2429 // Collect all OEM packages. 2430 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2431 scanDirTracedLI(oemAppDir, mDefParseFlags 2432 | PackageParser.PARSE_IS_SYSTEM 2433 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2434 2435 // Prune any system packages that no longer exist. 2436 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2437 if (!mOnlyCore) { 2438 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2439 while (psit.hasNext()) { 2440 PackageSetting ps = psit.next(); 2441 2442 /* 2443 * If this is not a system app, it can't be a 2444 * disable system app. 2445 */ 2446 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2447 continue; 2448 } 2449 2450 /* 2451 * If the package is scanned, it's not erased. 2452 */ 2453 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2454 if (scannedPkg != null) { 2455 /* 2456 * If the system app is both scanned and in the 2457 * disabled packages list, then it must have been 2458 * added via OTA. Remove it from the currently 2459 * scanned package so the previously user-installed 2460 * application can be scanned. 2461 */ 2462 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2463 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2464 + ps.name + "; removing system app. Last known codePath=" 2465 + ps.codePathString + ", installStatus=" + ps.installStatus 2466 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2467 + scannedPkg.mVersionCode); 2468 removePackageLI(scannedPkg, true); 2469 mExpectingBetter.put(ps.name, ps.codePath); 2470 } 2471 2472 continue; 2473 } 2474 2475 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2476 psit.remove(); 2477 logCriticalInfo(Log.WARN, "System package " + ps.name 2478 + " no longer exists; it's data will be wiped"); 2479 // Actual deletion of code and data will be handled by later 2480 // reconciliation step 2481 } else { 2482 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2483 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2484 possiblyDeletedUpdatedSystemApps.add(ps.name); 2485 } 2486 } 2487 } 2488 } 2489 2490 //look for any incomplete package installations 2491 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2492 for (int i = 0; i < deletePkgsList.size(); i++) { 2493 // Actual deletion of code and data will be handled by later 2494 // reconciliation step 2495 final String packageName = deletePkgsList.get(i).name; 2496 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2497 synchronized (mPackages) { 2498 mSettings.removePackageLPw(packageName); 2499 } 2500 } 2501 2502 //delete tmp files 2503 deleteTempPackageFiles(); 2504 2505 // Remove any shared userIDs that have no associated packages 2506 mSettings.pruneSharedUsersLPw(); 2507 2508 if (!mOnlyCore) { 2509 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2510 SystemClock.uptimeMillis()); 2511 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2512 2513 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2514 | PackageParser.PARSE_FORWARD_LOCK, 2515 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2516 2517 scanDirLI(mEphemeralInstallDir, mDefParseFlags 2518 | PackageParser.PARSE_IS_EPHEMERAL, 2519 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2520 2521 /** 2522 * Remove disable package settings for any updated system 2523 * apps that were removed via an OTA. If they're not a 2524 * previously-updated app, remove them completely. 2525 * Otherwise, just revoke their system-level permissions. 2526 */ 2527 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2528 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2529 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2530 2531 String msg; 2532 if (deletedPkg == null) { 2533 msg = "Updated system package " + deletedAppName 2534 + " no longer exists; it's data will be wiped"; 2535 // Actual deletion of code and data will be handled by later 2536 // reconciliation step 2537 } else { 2538 msg = "Updated system app + " + deletedAppName 2539 + " no longer present; removing system privileges for " 2540 + deletedAppName; 2541 2542 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2543 2544 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2545 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2546 } 2547 logCriticalInfo(Log.WARN, msg); 2548 } 2549 2550 /** 2551 * Make sure all system apps that we expected to appear on 2552 * the userdata partition actually showed up. If they never 2553 * appeared, crawl back and revive the system version. 2554 */ 2555 for (int i = 0; i < mExpectingBetter.size(); i++) { 2556 final String packageName = mExpectingBetter.keyAt(i); 2557 if (!mPackages.containsKey(packageName)) { 2558 final File scanFile = mExpectingBetter.valueAt(i); 2559 2560 logCriticalInfo(Log.WARN, "Expected better " + packageName 2561 + " but never showed up; reverting to system"); 2562 2563 int reparseFlags = mDefParseFlags; 2564 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2565 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2566 | PackageParser.PARSE_IS_SYSTEM_DIR 2567 | PackageParser.PARSE_IS_PRIVILEGED; 2568 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2569 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2570 | PackageParser.PARSE_IS_SYSTEM_DIR; 2571 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2572 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2573 | PackageParser.PARSE_IS_SYSTEM_DIR; 2574 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2575 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2576 | PackageParser.PARSE_IS_SYSTEM_DIR; 2577 } else { 2578 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2579 continue; 2580 } 2581 2582 mSettings.enableSystemPackageLPw(packageName); 2583 2584 try { 2585 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2586 } catch (PackageManagerException e) { 2587 Slog.e(TAG, "Failed to parse original system package: " 2588 + e.getMessage()); 2589 } 2590 } 2591 } 2592 } 2593 mExpectingBetter.clear(); 2594 2595 // Resolve the storage manager. 2596 mStorageManagerPackage = getStorageManagerPackageName(); 2597 2598 // Resolve protected action filters. Only the setup wizard is allowed to 2599 // have a high priority filter for these actions. 2600 mSetupWizardPackage = getSetupWizardPackageName(); 2601 if (mProtectedFilters.size() > 0) { 2602 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2603 Slog.i(TAG, "No setup wizard;" 2604 + " All protected intents capped to priority 0"); 2605 } 2606 for (ActivityIntentInfo filter : mProtectedFilters) { 2607 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2608 if (DEBUG_FILTERS) { 2609 Slog.i(TAG, "Found setup wizard;" 2610 + " allow priority " + filter.getPriority() + ";" 2611 + " package: " + filter.activity.info.packageName 2612 + " activity: " + filter.activity.className 2613 + " priority: " + filter.getPriority()); 2614 } 2615 // skip setup wizard; allow it to keep the high priority filter 2616 continue; 2617 } 2618 Slog.w(TAG, "Protected action; cap priority to 0;" 2619 + " package: " + filter.activity.info.packageName 2620 + " activity: " + filter.activity.className 2621 + " origPrio: " + filter.getPriority()); 2622 filter.setPriority(0); 2623 } 2624 } 2625 mDeferProtectedFilters = false; 2626 mProtectedFilters.clear(); 2627 2628 // Now that we know all of the shared libraries, update all clients to have 2629 // the correct library paths. 2630 updateAllSharedLibrariesLPw(); 2631 2632 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2633 // NOTE: We ignore potential failures here during a system scan (like 2634 // the rest of the commands above) because there's precious little we 2635 // can do about it. A settings error is reported, though. 2636 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/); 2637 } 2638 2639 // Now that we know all the packages we are keeping, 2640 // read and update their last usage times. 2641 mPackageUsage.read(mPackages); 2642 mCompilerStats.read(); 2643 2644 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2645 SystemClock.uptimeMillis()); 2646 Slog.i(TAG, "Time to scan packages: " 2647 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2648 + " seconds"); 2649 2650 // If the platform SDK has changed since the last time we booted, 2651 // we need to re-grant app permission to catch any new ones that 2652 // appear. This is really a hack, and means that apps can in some 2653 // cases get permissions that the user didn't initially explicitly 2654 // allow... it would be nice to have some better way to handle 2655 // this situation. 2656 int updateFlags = UPDATE_PERMISSIONS_ALL; 2657 if (ver.sdkVersion != mSdkVersion) { 2658 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2659 + mSdkVersion + "; regranting permissions for internal storage"); 2660 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2661 } 2662 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2663 ver.sdkVersion = mSdkVersion; 2664 2665 // If this is the first boot or an update from pre-M, and it is a normal 2666 // boot, then we need to initialize the default preferred apps across 2667 // all defined users. 2668 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2669 for (UserInfo user : sUserManager.getUsers(true)) { 2670 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2671 applyFactoryDefaultBrowserLPw(user.id); 2672 primeDomainVerificationsLPw(user.id); 2673 } 2674 } 2675 2676 // Prepare storage for system user really early during boot, 2677 // since core system apps like SettingsProvider and SystemUI 2678 // can't wait for user to start 2679 final int storageFlags; 2680 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2681 storageFlags = StorageManager.FLAG_STORAGE_DE; 2682 } else { 2683 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2684 } 2685 reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2686 storageFlags, true /* migrateAppData */); 2687 2688 // If this is first boot after an OTA, and a normal boot, then 2689 // we need to clear code cache directories. 2690 // Note that we do *not* clear the application profiles. These remain valid 2691 // across OTAs and are used to drive profile verification (post OTA) and 2692 // profile compilation (without waiting to collect a fresh set of profiles). 2693 if (mIsUpgrade && !onlyCore) { 2694 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2695 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2696 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2697 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2698 // No apps are running this early, so no need to freeze 2699 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2700 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2701 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2702 } 2703 } 2704 ver.fingerprint = Build.FINGERPRINT; 2705 } 2706 2707 checkDefaultBrowser(); 2708 2709 // clear only after permissions and other defaults have been updated 2710 mExistingSystemPackages.clear(); 2711 mPromoteSystemApps = false; 2712 2713 // All the changes are done during package scanning. 2714 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2715 2716 // can downgrade to reader 2717 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings"); 2718 mSettings.writeLPr(); 2719 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2720 2721 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2722 // early on (before the package manager declares itself as early) because other 2723 // components in the system server might ask for package contexts for these apps. 2724 // 2725 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2726 // (i.e, that the data partition is unavailable). 2727 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2728 long start = System.nanoTime(); 2729 List<PackageParser.Package> coreApps = new ArrayList<>(); 2730 for (PackageParser.Package pkg : mPackages.values()) { 2731 if (pkg.coreApp) { 2732 coreApps.add(pkg); 2733 } 2734 } 2735 2736 int[] stats = performDexOptUpgrade(coreApps, false, 2737 getCompilerFilterForReason(REASON_CORE_APP)); 2738 2739 final int elapsedTimeSeconds = 2740 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2741 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2742 2743 if (DEBUG_DEXOPT) { 2744 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2745 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2746 } 2747 2748 2749 // TODO: Should we log these stats to tron too ? 2750 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2751 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2752 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2753 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2754 } 2755 2756 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2757 SystemClock.uptimeMillis()); 2758 2759 if (!mOnlyCore) { 2760 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2761 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2762 mRequiredUninstallerPackage = getRequiredUninstallerLPr(); 2763 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2764 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2765 mIntentFilterVerifierComponent); 2766 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2767 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 2768 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2769 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED); 2770 } else { 2771 mRequiredVerifierPackage = null; 2772 mRequiredInstallerPackage = null; 2773 mRequiredUninstallerPackage = null; 2774 mIntentFilterVerifierComponent = null; 2775 mIntentFilterVerifier = null; 2776 mServicesSystemSharedLibraryPackageName = null; 2777 mSharedSystemSharedLibraryPackageName = null; 2778 } 2779 2780 mInstallerService = new PackageInstallerService(context, this); 2781 2782 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2783 if (ephemeralResolverComponent != null) { 2784 if (DEBUG_EPHEMERAL) { 2785 Slog.i(TAG, "Ephemeral resolver: " + ephemeralResolverComponent); 2786 } 2787 mEphemeralResolverConnection = 2788 new EphemeralResolverConnection(mContext, ephemeralResolverComponent); 2789 } else { 2790 mEphemeralResolverConnection = null; 2791 } 2792 mEphemeralInstallerComponent = getEphemeralInstallerLPr(); 2793 if (mEphemeralInstallerComponent != null) { 2794 if (DEBUG_EPHEMERAL) { 2795 Slog.i(TAG, "Ephemeral installer: " + mEphemeralInstallerComponent); 2796 } 2797 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2798 } 2799 2800 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2801 2802 // Read and update the usage of dex files. 2803 // Do this at the end of PM init so that all the packages have their 2804 // data directory reconciled. 2805 // At this point we know the code paths of the packages, so we can validate 2806 // the disk file and build the internal cache. 2807 // The usage file is expected to be small so loading and verifying it 2808 // should take a fairly small time compare to the other activities (e.g. package 2809 // scanning). 2810 final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>(); 2811 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 2812 for (int userId : currentUserIds) { 2813 userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList()); 2814 } 2815 mDexManager.load(userPackages); 2816 } // synchronized (mPackages) 2817 } // synchronized (mInstallLock) 2818 2819 // Now after opening every single application zip, make sure they 2820 // are all flushed. Not really needed, but keeps things nice and 2821 // tidy. 2822 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC"); 2823 Runtime.getRuntime().gc(); 2824 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2825 2826 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks"); 2827 FallbackCategoryProvider.loadFallbacks(); 2828 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2829 2830 // The initial scanning above does many calls into installd while 2831 // holding the mPackages lock, but we're mostly interested in yelling 2832 // once we have a booted system. 2833 mInstaller.setWarnIfHeld(mPackages); 2834 2835 // Expose private service for system components to use. 2836 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2837 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2838 } 2839 2840 private static File preparePackageParserCache(boolean isUpgrade) { 2841 if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) { 2842 return null; 2843 } 2844 2845 if (SystemProperties.getBoolean("ro.boot.disable_package_cache", false)) { 2846 Slog.i(TAG, "Disabling package parser cache due to system property."); 2847 return null; 2848 } 2849 2850 // The base directory for the package parser cache lives under /data/system/. 2851 final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(), 2852 "package_cache"); 2853 if (cacheBaseDir == null) { 2854 return null; 2855 } 2856 2857 // If this is a system upgrade scenario, delete the contents of the package cache dir. 2858 // This also serves to "GC" unused entries when the package cache version changes (which 2859 // can only happen during upgrades). 2860 if (isUpgrade) { 2861 FileUtils.deleteContents(cacheBaseDir); 2862 } 2863 2864 // Return the versioned package cache directory. This is something like 2865 // "/data/system/package_cache/1" 2866 return FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION); 2867 } 2868 2869 @Override 2870 public boolean isFirstBoot() { 2871 return mFirstBoot; 2872 } 2873 2874 @Override 2875 public boolean isOnlyCoreApps() { 2876 return mOnlyCore; 2877 } 2878 2879 @Override 2880 public boolean isUpgrade() { 2881 return mIsUpgrade; 2882 } 2883 2884 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2885 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2886 2887 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2888 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2889 UserHandle.USER_SYSTEM); 2890 if (matches.size() == 1) { 2891 return matches.get(0).getComponentInfo().packageName; 2892 } else if (matches.size() == 0) { 2893 Log.e(TAG, "There should probably be a verifier, but, none were found"); 2894 return null; 2895 } 2896 throw new RuntimeException("There must be exactly one verifier; found " + matches); 2897 } 2898 2899 private @NonNull String getRequiredSharedLibraryLPr(String libraryName) { 2900 synchronized (mPackages) { 2901 SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName); 2902 if (libraryEntry == null) { 2903 throw new IllegalStateException("Missing required shared library:" + libraryName); 2904 } 2905 return libraryEntry.apk; 2906 } 2907 } 2908 2909 private @NonNull String getRequiredInstallerLPr() { 2910 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2911 intent.addCategory(Intent.CATEGORY_DEFAULT); 2912 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2913 2914 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2915 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2916 UserHandle.USER_SYSTEM); 2917 if (matches.size() == 1) { 2918 ResolveInfo resolveInfo = matches.get(0); 2919 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 2920 throw new RuntimeException("The installer must be a privileged app"); 2921 } 2922 return matches.get(0).getComponentInfo().packageName; 2923 } else { 2924 throw new RuntimeException("There must be exactly one installer; found " + matches); 2925 } 2926 } 2927 2928 private @NonNull String getRequiredUninstallerLPr() { 2929 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 2930 intent.addCategory(Intent.CATEGORY_DEFAULT); 2931 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null)); 2932 2933 final ResolveInfo resolveInfo = resolveIntent(intent, null, 2934 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2935 UserHandle.USER_SYSTEM); 2936 if (resolveInfo == null || 2937 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) { 2938 throw new RuntimeException("There must be exactly one uninstaller; found " 2939 + resolveInfo); 2940 } 2941 return resolveInfo.getComponentInfo().packageName; 2942 } 2943 2944 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2945 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2946 2947 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2948 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2949 UserHandle.USER_SYSTEM); 2950 ResolveInfo best = null; 2951 final int N = matches.size(); 2952 for (int i = 0; i < N; i++) { 2953 final ResolveInfo cur = matches.get(i); 2954 final String packageName = cur.getComponentInfo().packageName; 2955 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2956 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2957 continue; 2958 } 2959 2960 if (best == null || cur.priority > best.priority) { 2961 best = cur; 2962 } 2963 } 2964 2965 if (best != null) { 2966 return best.getComponentInfo().getComponentName(); 2967 } else { 2968 throw new RuntimeException("There must be at least one intent filter verifier"); 2969 } 2970 } 2971 2972 private @Nullable ComponentName getEphemeralResolverLPr() { 2973 final String[] packageArray = 2974 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2975 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 2976 if (DEBUG_EPHEMERAL) { 2977 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2978 } 2979 return null; 2980 } 2981 2982 final int resolveFlags = 2983 MATCH_DIRECT_BOOT_AWARE 2984 | MATCH_DIRECT_BOOT_UNAWARE 2985 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2986 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2987 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2988 resolveFlags, UserHandle.USER_SYSTEM); 2989 2990 final int N = resolvers.size(); 2991 if (N == 0) { 2992 if (DEBUG_EPHEMERAL) { 2993 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2994 } 2995 return null; 2996 } 2997 2998 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2999 for (int i = 0; i < N; i++) { 3000 final ResolveInfo info = resolvers.get(i); 3001 3002 if (info.serviceInfo == null) { 3003 continue; 3004 } 3005 3006 final String packageName = info.serviceInfo.packageName; 3007 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 3008 if (DEBUG_EPHEMERAL) { 3009 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 3010 + " pkg: " + packageName + ", info:" + info); 3011 } 3012 continue; 3013 } 3014 3015 if (DEBUG_EPHEMERAL) { 3016 Slog.v(TAG, "Ephemeral resolver found;" 3017 + " pkg: " + packageName + ", info:" + info); 3018 } 3019 return new ComponentName(packageName, info.serviceInfo.name); 3020 } 3021 if (DEBUG_EPHEMERAL) { 3022 Slog.v(TAG, "Ephemeral resolver NOT found"); 3023 } 3024 return null; 3025 } 3026 3027 private @Nullable ComponentName getEphemeralInstallerLPr() { 3028 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 3029 intent.addCategory(Intent.CATEGORY_DEFAULT); 3030 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 3031 3032 final int resolveFlags = 3033 MATCH_DIRECT_BOOT_AWARE 3034 | MATCH_DIRECT_BOOT_UNAWARE 3035 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 3036 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 3037 resolveFlags, UserHandle.USER_SYSTEM); 3038 Iterator<ResolveInfo> iter = matches.iterator(); 3039 while (iter.hasNext()) { 3040 final ResolveInfo rInfo = iter.next(); 3041 final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName); 3042 if (ps != null) { 3043 final PermissionsState permissionsState = ps.getPermissionsState(); 3044 if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) { 3045 continue; 3046 } 3047 } 3048 iter.remove(); 3049 } 3050 if (matches.size() == 0) { 3051 return null; 3052 } else if (matches.size() == 1) { 3053 return matches.get(0).getComponentInfo().getComponentName(); 3054 } else { 3055 throw new RuntimeException( 3056 "There must be at most one ephemeral installer; found " + matches); 3057 } 3058 } 3059 3060 private void primeDomainVerificationsLPw(int userId) { 3061 if (DEBUG_DOMAIN_VERIFICATION) { 3062 Slog.d(TAG, "Priming domain verifications in user " + userId); 3063 } 3064 3065 SystemConfig systemConfig = SystemConfig.getInstance(); 3066 ArraySet<String> packages = systemConfig.getLinkedApps(); 3067 3068 for (String packageName : packages) { 3069 PackageParser.Package pkg = mPackages.get(packageName); 3070 if (pkg != null) { 3071 if (!pkg.isSystemApp()) { 3072 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 3073 continue; 3074 } 3075 3076 ArraySet<String> domains = null; 3077 for (PackageParser.Activity a : pkg.activities) { 3078 for (ActivityIntentInfo filter : a.intents) { 3079 if (hasValidDomains(filter)) { 3080 if (domains == null) { 3081 domains = new ArraySet<String>(); 3082 } 3083 domains.addAll(filter.getHostsList()); 3084 } 3085 } 3086 } 3087 3088 if (domains != null && domains.size() > 0) { 3089 if (DEBUG_DOMAIN_VERIFICATION) { 3090 Slog.v(TAG, " + " + packageName); 3091 } 3092 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 3093 // state w.r.t. the formal app-linkage "no verification attempted" state; 3094 // and then 'always' in the per-user state actually used for intent resolution. 3095 final IntentFilterVerificationInfo ivi; 3096 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains); 3097 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 3098 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 3099 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 3100 } else { 3101 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 3102 + "' does not handle web links"); 3103 } 3104 } else { 3105 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 3106 } 3107 } 3108 3109 scheduleWritePackageRestrictionsLocked(userId); 3110 scheduleWriteSettingsLocked(); 3111 } 3112 3113 private void applyFactoryDefaultBrowserLPw(int userId) { 3114 // The default browser app's package name is stored in a string resource, 3115 // with a product-specific overlay used for vendor customization. 3116 String browserPkg = mContext.getResources().getString( 3117 com.android.internal.R.string.default_browser); 3118 if (!TextUtils.isEmpty(browserPkg)) { 3119 // non-empty string => required to be a known package 3120 PackageSetting ps = mSettings.mPackages.get(browserPkg); 3121 if (ps == null) { 3122 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 3123 browserPkg = null; 3124 } else { 3125 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3126 } 3127 } 3128 3129 // Nothing valid explicitly set? Make the factory-installed browser the explicit 3130 // default. If there's more than one, just leave everything alone. 3131 if (browserPkg == null) { 3132 calculateDefaultBrowserLPw(userId); 3133 } 3134 } 3135 3136 private void calculateDefaultBrowserLPw(int userId) { 3137 List<String> allBrowsers = resolveAllBrowserApps(userId); 3138 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 3139 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 3140 } 3141 3142 private List<String> resolveAllBrowserApps(int userId) { 3143 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 3144 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3145 PackageManager.MATCH_ALL, userId); 3146 3147 final int count = list.size(); 3148 List<String> result = new ArrayList<String>(count); 3149 for (int i=0; i<count; i++) { 3150 ResolveInfo info = list.get(i); 3151 if (info.activityInfo == null 3152 || !info.handleAllWebDataURI 3153 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 3154 || result.contains(info.activityInfo.packageName)) { 3155 continue; 3156 } 3157 result.add(info.activityInfo.packageName); 3158 } 3159 3160 return result; 3161 } 3162 3163 private boolean packageIsBrowser(String packageName, int userId) { 3164 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3165 PackageManager.MATCH_ALL, userId); 3166 final int N = list.size(); 3167 for (int i = 0; i < N; i++) { 3168 ResolveInfo info = list.get(i); 3169 if (packageName.equals(info.activityInfo.packageName)) { 3170 return true; 3171 } 3172 } 3173 return false; 3174 } 3175 3176 private void checkDefaultBrowser() { 3177 final int myUserId = UserHandle.myUserId(); 3178 final String packageName = getDefaultBrowserPackageName(myUserId); 3179 if (packageName != null) { 3180 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 3181 if (info == null) { 3182 Slog.w(TAG, "Default browser no longer installed: " + packageName); 3183 synchronized (mPackages) { 3184 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 3185 } 3186 } 3187 } 3188 } 3189 3190 @Override 3191 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 3192 throws RemoteException { 3193 try { 3194 return super.onTransact(code, data, reply, flags); 3195 } catch (RuntimeException e) { 3196 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 3197 Slog.wtf(TAG, "Package Manager Crash", e); 3198 } 3199 throw e; 3200 } 3201 } 3202 3203 static int[] appendInts(int[] cur, int[] add) { 3204 if (add == null) return cur; 3205 if (cur == null) return add; 3206 final int N = add.length; 3207 for (int i=0; i<N; i++) { 3208 cur = appendInt(cur, add[i]); 3209 } 3210 return cur; 3211 } 3212 3213 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3214 if (!sUserManager.exists(userId)) return null; 3215 if (ps == null) { 3216 return null; 3217 } 3218 final PackageParser.Package p = ps.pkg; 3219 if (p == null) { 3220 return null; 3221 } 3222 3223 final PermissionsState permissionsState = ps.getPermissionsState(); 3224 3225 // Compute GIDs only if requested 3226 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3227 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3228 // Compute granted permissions only if package has requested permissions 3229 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3230 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3231 final PackageUserState state = ps.readUserState(userId); 3232 3233 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 3234 && ps.isSystem()) { 3235 flags |= MATCH_ANY_USER; 3236 } 3237 3238 return PackageParser.generatePackageInfo(p, gids, flags, 3239 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3240 } 3241 3242 @Override 3243 public void checkPackageStartable(String packageName, int userId) { 3244 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3245 3246 synchronized (mPackages) { 3247 final PackageSetting ps = mSettings.mPackages.get(packageName); 3248 if (ps == null) { 3249 throw new SecurityException("Package " + packageName + " was not found!"); 3250 } 3251 3252 if (!ps.getInstalled(userId)) { 3253 throw new SecurityException( 3254 "Package " + packageName + " was not installed for user " + userId + "!"); 3255 } 3256 3257 if (mSafeMode && !ps.isSystem()) { 3258 throw new SecurityException("Package " + packageName + " not a system app!"); 3259 } 3260 3261 if (mFrozenPackages.contains(packageName)) { 3262 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3263 } 3264 3265 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3266 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3267 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3268 } 3269 } 3270 } 3271 3272 @Override 3273 public boolean isPackageAvailable(String packageName, int userId) { 3274 if (!sUserManager.exists(userId)) return false; 3275 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3276 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3277 synchronized (mPackages) { 3278 PackageParser.Package p = mPackages.get(packageName); 3279 if (p != null) { 3280 final PackageSetting ps = (PackageSetting) p.mExtras; 3281 if (ps != null) { 3282 final PackageUserState state = ps.readUserState(userId); 3283 if (state != null) { 3284 return PackageParser.isAvailable(state); 3285 } 3286 } 3287 } 3288 } 3289 return false; 3290 } 3291 3292 @Override 3293 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3294 if (!sUserManager.exists(userId)) return null; 3295 flags = updateFlagsForPackage(flags, userId, packageName); 3296 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3297 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3298 3299 // reader 3300 synchronized (mPackages) { 3301 // Normalize package name to hanlde renamed packages 3302 packageName = normalizePackageNameLPr(packageName); 3303 3304 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3305 PackageParser.Package p = null; 3306 if (matchFactoryOnly) { 3307 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3308 if (ps != null) { 3309 return generatePackageInfo(ps, flags, userId); 3310 } 3311 } 3312 if (p == null) { 3313 p = mPackages.get(packageName); 3314 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3315 return null; 3316 } 3317 } 3318 if (DEBUG_PACKAGE_INFO) 3319 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3320 if (p != null) { 3321 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3322 } 3323 if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) { 3324 final PackageSetting ps = mSettings.mPackages.get(packageName); 3325 return generatePackageInfo(ps, flags, userId); 3326 } 3327 } 3328 return null; 3329 } 3330 3331 @Override 3332 public String[] currentToCanonicalPackageNames(String[] names) { 3333 String[] out = new String[names.length]; 3334 // reader 3335 synchronized (mPackages) { 3336 for (int i=names.length-1; i>=0; i--) { 3337 PackageSetting ps = mSettings.mPackages.get(names[i]); 3338 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3339 } 3340 } 3341 return out; 3342 } 3343 3344 @Override 3345 public String[] canonicalToCurrentPackageNames(String[] names) { 3346 String[] out = new String[names.length]; 3347 // reader 3348 synchronized (mPackages) { 3349 for (int i=names.length-1; i>=0; i--) { 3350 String cur = mSettings.getRenamedPackageLPr(names[i]); 3351 out[i] = cur != null ? cur : names[i]; 3352 } 3353 } 3354 return out; 3355 } 3356 3357 @Override 3358 public int getPackageUid(String packageName, int flags, int userId) { 3359 if (!sUserManager.exists(userId)) return -1; 3360 flags = updateFlagsForPackage(flags, userId, packageName); 3361 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3362 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3363 3364 // reader 3365 synchronized (mPackages) { 3366 final PackageParser.Package p = mPackages.get(packageName); 3367 if (p != null && p.isMatch(flags)) { 3368 return UserHandle.getUid(userId, p.applicationInfo.uid); 3369 } 3370 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3371 final PackageSetting ps = mSettings.mPackages.get(packageName); 3372 if (ps != null && ps.isMatch(flags)) { 3373 return UserHandle.getUid(userId, ps.appId); 3374 } 3375 } 3376 } 3377 3378 return -1; 3379 } 3380 3381 @Override 3382 public int[] getPackageGids(String packageName, int flags, int userId) { 3383 if (!sUserManager.exists(userId)) return null; 3384 flags = updateFlagsForPackage(flags, userId, packageName); 3385 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3386 false /* requireFullPermission */, false /* checkShell */, 3387 "getPackageGids"); 3388 3389 // reader 3390 synchronized (mPackages) { 3391 final PackageParser.Package p = mPackages.get(packageName); 3392 if (p != null && p.isMatch(flags)) { 3393 PackageSetting ps = (PackageSetting) p.mExtras; 3394 // TODO: Shouldn't this be checking for package installed state for userId and 3395 // return null? 3396 return ps.getPermissionsState().computeGids(userId); 3397 } 3398 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3399 final PackageSetting ps = mSettings.mPackages.get(packageName); 3400 if (ps != null && ps.isMatch(flags)) { 3401 return ps.getPermissionsState().computeGids(userId); 3402 } 3403 } 3404 } 3405 3406 return null; 3407 } 3408 3409 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3410 if (bp.perm != null) { 3411 return PackageParser.generatePermissionInfo(bp.perm, flags); 3412 } 3413 PermissionInfo pi = new PermissionInfo(); 3414 pi.name = bp.name; 3415 pi.packageName = bp.sourcePackage; 3416 pi.nonLocalizedLabel = bp.name; 3417 pi.protectionLevel = bp.protectionLevel; 3418 return pi; 3419 } 3420 3421 @Override 3422 public PermissionInfo getPermissionInfo(String name, int flags) { 3423 // reader 3424 synchronized (mPackages) { 3425 final BasePermission p = mSettings.mPermissions.get(name); 3426 if (p != null) { 3427 return generatePermissionInfo(p, flags); 3428 } 3429 return null; 3430 } 3431 } 3432 3433 @Override 3434 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3435 int flags) { 3436 // reader 3437 synchronized (mPackages) { 3438 if (group != null && !mPermissionGroups.containsKey(group)) { 3439 // This is thrown as NameNotFoundException 3440 return null; 3441 } 3442 3443 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3444 for (BasePermission p : mSettings.mPermissions.values()) { 3445 if (group == null) { 3446 if (p.perm == null || p.perm.info.group == null) { 3447 out.add(generatePermissionInfo(p, flags)); 3448 } 3449 } else { 3450 if (p.perm != null && group.equals(p.perm.info.group)) { 3451 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3452 } 3453 } 3454 } 3455 return new ParceledListSlice<>(out); 3456 } 3457 } 3458 3459 @Override 3460 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3461 // reader 3462 synchronized (mPackages) { 3463 return PackageParser.generatePermissionGroupInfo( 3464 mPermissionGroups.get(name), flags); 3465 } 3466 } 3467 3468 @Override 3469 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3470 // reader 3471 synchronized (mPackages) { 3472 final int N = mPermissionGroups.size(); 3473 ArrayList<PermissionGroupInfo> out 3474 = new ArrayList<PermissionGroupInfo>(N); 3475 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3476 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3477 } 3478 return new ParceledListSlice<>(out); 3479 } 3480 } 3481 3482 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3483 int userId) { 3484 if (!sUserManager.exists(userId)) return null; 3485 PackageSetting ps = mSettings.mPackages.get(packageName); 3486 if (ps != null) { 3487 if (ps.pkg == null) { 3488 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3489 if (pInfo != null) { 3490 return pInfo.applicationInfo; 3491 } 3492 return null; 3493 } 3494 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3495 ps.readUserState(userId), userId); 3496 } 3497 return null; 3498 } 3499 3500 @Override 3501 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3502 if (!sUserManager.exists(userId)) return null; 3503 flags = updateFlagsForApplication(flags, userId, packageName); 3504 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3505 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3506 3507 // writer 3508 synchronized (mPackages) { 3509 // Normalize package name to hanlde renamed packages 3510 packageName = normalizePackageNameLPr(packageName); 3511 3512 PackageParser.Package p = mPackages.get(packageName); 3513 if (DEBUG_PACKAGE_INFO) Log.v( 3514 TAG, "getApplicationInfo " + packageName 3515 + ": " + p); 3516 if (p != null) { 3517 PackageSetting ps = mSettings.mPackages.get(packageName); 3518 if (ps == null) return null; 3519 // Note: isEnabledLP() does not apply here - always return info 3520 return PackageParser.generateApplicationInfo( 3521 p, flags, ps.readUserState(userId), userId); 3522 } 3523 if ("android".equals(packageName)||"system".equals(packageName)) { 3524 return mAndroidApplication; 3525 } 3526 if ((flags & MATCH_KNOWN_PACKAGES) != 0) { 3527 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3528 } 3529 } 3530 return null; 3531 } 3532 3533 private String normalizePackageNameLPr(String packageName) { 3534 String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName); 3535 return normalizedPackageName != null ? normalizedPackageName : packageName; 3536 } 3537 3538 @Override 3539 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3540 final IPackageDataObserver observer) { 3541 mContext.enforceCallingOrSelfPermission( 3542 android.Manifest.permission.CLEAR_APP_CACHE, null); 3543 // Queue up an async operation since clearing cache may take a little while. 3544 mHandler.post(new Runnable() { 3545 public void run() { 3546 mHandler.removeCallbacks(this); 3547 boolean success = true; 3548 synchronized (mInstallLock) { 3549 try { 3550 mInstaller.freeCache(volumeUuid, freeStorageSize); 3551 } catch (InstallerException e) { 3552 Slog.w(TAG, "Couldn't clear application caches: " + e); 3553 success = false; 3554 } 3555 } 3556 if (observer != null) { 3557 try { 3558 observer.onRemoveCompleted(null, success); 3559 } catch (RemoteException e) { 3560 Slog.w(TAG, "RemoveException when invoking call back"); 3561 } 3562 } 3563 } 3564 }); 3565 } 3566 3567 @Override 3568 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3569 final IntentSender pi) { 3570 mContext.enforceCallingOrSelfPermission( 3571 android.Manifest.permission.CLEAR_APP_CACHE, null); 3572 // Queue up an async operation since clearing cache may take a little while. 3573 mHandler.post(new Runnable() { 3574 public void run() { 3575 mHandler.removeCallbacks(this); 3576 boolean success = true; 3577 synchronized (mInstallLock) { 3578 try { 3579 mInstaller.freeCache(volumeUuid, freeStorageSize); 3580 } catch (InstallerException e) { 3581 Slog.w(TAG, "Couldn't clear application caches: " + e); 3582 success = false; 3583 } 3584 } 3585 if(pi != null) { 3586 try { 3587 // Callback via pending intent 3588 int code = success ? 1 : 0; 3589 pi.sendIntent(null, code, null, 3590 null, null); 3591 } catch (SendIntentException e1) { 3592 Slog.i(TAG, "Failed to send pending intent"); 3593 } 3594 } 3595 } 3596 }); 3597 } 3598 3599 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3600 synchronized (mInstallLock) { 3601 try { 3602 mInstaller.freeCache(volumeUuid, freeStorageSize); 3603 } catch (InstallerException e) { 3604 throw new IOException("Failed to free enough space", e); 3605 } 3606 } 3607 } 3608 3609 /** 3610 * Update given flags based on encryption status of current user. 3611 */ 3612 private int updateFlags(int flags, int userId) { 3613 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3614 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3615 // Caller expressed an explicit opinion about what encryption 3616 // aware/unaware components they want to see, so fall through and 3617 // give them what they want 3618 } else { 3619 // Caller expressed no opinion, so match based on user state 3620 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3621 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3622 } else { 3623 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3624 } 3625 } 3626 return flags; 3627 } 3628 3629 private UserManagerInternal getUserManagerInternal() { 3630 if (mUserManagerInternal == null) { 3631 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3632 } 3633 return mUserManagerInternal; 3634 } 3635 3636 /** 3637 * Update given flags when being used to request {@link PackageInfo}. 3638 */ 3639 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3640 final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM; 3641 boolean triaged = true; 3642 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3643 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3644 // Caller is asking for component details, so they'd better be 3645 // asking for specific encryption matching behavior, or be triaged 3646 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3647 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3648 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3649 triaged = false; 3650 } 3651 } 3652 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3653 | PackageManager.MATCH_SYSTEM_ONLY 3654 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3655 triaged = false; 3656 } 3657 if ((flags & PackageManager.MATCH_ANY_USER) != 0) { 3658 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, 3659 "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at " 3660 + Debug.getCallers(5)); 3661 } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser 3662 && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) { 3663 // If the caller wants all packages and has a restricted profile associated with it, 3664 // then match all users. This is to make sure that launchers that need to access work 3665 // profile apps don't start breaking. TODO: Remove this hack when launchers stop using 3666 // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380 3667 flags |= PackageManager.MATCH_ANY_USER; 3668 } 3669 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3670 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3671 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3672 } 3673 return updateFlags(flags, userId); 3674 } 3675 3676 /** 3677 * Update given flags when being used to request {@link ApplicationInfo}. 3678 */ 3679 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3680 return updateFlagsForPackage(flags, userId, cookie); 3681 } 3682 3683 /** 3684 * Update given flags when being used to request {@link ComponentInfo}. 3685 */ 3686 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3687 if (cookie instanceof Intent) { 3688 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3689 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3690 } 3691 } 3692 3693 boolean triaged = true; 3694 // Caller is asking for component details, so they'd better be 3695 // asking for specific encryption matching behavior, or be triaged 3696 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3697 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3698 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3699 triaged = false; 3700 } 3701 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3702 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3703 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3704 } 3705 3706 return updateFlags(flags, userId); 3707 } 3708 3709 /** 3710 * Update given flags when being used to request {@link ResolveInfo}. 3711 */ 3712 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3713 // Safe mode means we shouldn't match any third-party components 3714 if (mSafeMode) { 3715 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3716 } 3717 final String ephemeralPkgName = getEphemeralPackageName(Binder.getCallingUid()); 3718 if (ephemeralPkgName != null) { 3719 flags |= PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY; 3720 flags |= PackageManager.MATCH_EPHEMERAL; 3721 } 3722 3723 return updateFlagsForComponent(flags, userId, cookie); 3724 } 3725 3726 @Override 3727 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3728 if (!sUserManager.exists(userId)) return null; 3729 flags = updateFlagsForComponent(flags, userId, component); 3730 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3731 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3732 synchronized (mPackages) { 3733 PackageParser.Activity a = mActivities.mActivities.get(component); 3734 3735 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3736 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3737 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3738 if (ps == null) return null; 3739 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3740 userId); 3741 } 3742 if (mResolveComponentName.equals(component)) { 3743 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3744 new PackageUserState(), userId); 3745 } 3746 } 3747 return null; 3748 } 3749 3750 @Override 3751 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3752 String resolvedType) { 3753 synchronized (mPackages) { 3754 if (component.equals(mResolveComponentName)) { 3755 // The resolver supports EVERYTHING! 3756 return true; 3757 } 3758 PackageParser.Activity a = mActivities.mActivities.get(component); 3759 if (a == null) { 3760 return false; 3761 } 3762 for (int i=0; i<a.intents.size(); i++) { 3763 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3764 intent.getData(), intent.getCategories(), TAG) >= 0) { 3765 return true; 3766 } 3767 } 3768 return false; 3769 } 3770 } 3771 3772 @Override 3773 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3774 if (!sUserManager.exists(userId)) return null; 3775 flags = updateFlagsForComponent(flags, userId, component); 3776 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3777 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3778 synchronized (mPackages) { 3779 PackageParser.Activity a = mReceivers.mActivities.get(component); 3780 if (DEBUG_PACKAGE_INFO) Log.v( 3781 TAG, "getReceiverInfo " + component + ": " + a); 3782 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3783 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3784 if (ps == null) return null; 3785 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3786 userId); 3787 } 3788 } 3789 return null; 3790 } 3791 3792 @Override 3793 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3794 if (!sUserManager.exists(userId)) return null; 3795 flags = updateFlagsForComponent(flags, userId, component); 3796 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3797 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3798 synchronized (mPackages) { 3799 PackageParser.Service s = mServices.mServices.get(component); 3800 if (DEBUG_PACKAGE_INFO) Log.v( 3801 TAG, "getServiceInfo " + component + ": " + s); 3802 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3803 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3804 if (ps == null) return null; 3805 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3806 userId); 3807 } 3808 } 3809 return null; 3810 } 3811 3812 @Override 3813 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3814 if (!sUserManager.exists(userId)) return null; 3815 flags = updateFlagsForComponent(flags, userId, component); 3816 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3817 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3818 synchronized (mPackages) { 3819 PackageParser.Provider p = mProviders.mProviders.get(component); 3820 if (DEBUG_PACKAGE_INFO) Log.v( 3821 TAG, "getProviderInfo " + component + ": " + p); 3822 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3823 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3824 if (ps == null) return null; 3825 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3826 userId); 3827 } 3828 } 3829 return null; 3830 } 3831 3832 @Override 3833 public String[] getSystemSharedLibraryNames() { 3834 Set<String> libSet; 3835 synchronized (mPackages) { 3836 libSet = mSharedLibraries.keySet(); 3837 int size = libSet.size(); 3838 if (size > 0) { 3839 String[] libs = new String[size]; 3840 libSet.toArray(libs); 3841 return libs; 3842 } 3843 } 3844 return null; 3845 } 3846 3847 @Override 3848 public @NonNull String getServicesSystemSharedLibraryPackageName() { 3849 synchronized (mPackages) { 3850 return mServicesSystemSharedLibraryPackageName; 3851 } 3852 } 3853 3854 @Override 3855 public @NonNull String getSharedSystemSharedLibraryPackageName() { 3856 synchronized (mPackages) { 3857 return mSharedSystemSharedLibraryPackageName; 3858 } 3859 } 3860 3861 @Override 3862 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3863 synchronized (mPackages) { 3864 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3865 3866 final FeatureInfo fi = new FeatureInfo(); 3867 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3868 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3869 res.add(fi); 3870 3871 return new ParceledListSlice<>(res); 3872 } 3873 } 3874 3875 @Override 3876 public boolean hasSystemFeature(String name, int version) { 3877 synchronized (mPackages) { 3878 final FeatureInfo feat = mAvailableFeatures.get(name); 3879 if (feat == null) { 3880 return false; 3881 } else { 3882 return feat.version >= version; 3883 } 3884 } 3885 } 3886 3887 @Override 3888 public int checkPermission(String permName, String pkgName, int userId) { 3889 if (!sUserManager.exists(userId)) { 3890 return PackageManager.PERMISSION_DENIED; 3891 } 3892 3893 synchronized (mPackages) { 3894 final PackageParser.Package p = mPackages.get(pkgName); 3895 if (p != null && p.mExtras != null) { 3896 final PackageSetting ps = (PackageSetting) p.mExtras; 3897 final PermissionsState permissionsState = ps.getPermissionsState(); 3898 if (permissionsState.hasPermission(permName, userId)) { 3899 return PackageManager.PERMISSION_GRANTED; 3900 } 3901 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3902 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3903 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3904 return PackageManager.PERMISSION_GRANTED; 3905 } 3906 } 3907 } 3908 3909 return PackageManager.PERMISSION_DENIED; 3910 } 3911 3912 @Override 3913 public int checkUidPermission(String permName, int uid) { 3914 final int userId = UserHandle.getUserId(uid); 3915 3916 if (!sUserManager.exists(userId)) { 3917 return PackageManager.PERMISSION_DENIED; 3918 } 3919 3920 synchronized (mPackages) { 3921 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3922 if (obj != null) { 3923 final SettingBase ps = (SettingBase) obj; 3924 final PermissionsState permissionsState = ps.getPermissionsState(); 3925 if (permissionsState.hasPermission(permName, userId)) { 3926 return PackageManager.PERMISSION_GRANTED; 3927 } 3928 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3929 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3930 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3931 return PackageManager.PERMISSION_GRANTED; 3932 } 3933 } else { 3934 ArraySet<String> perms = mSystemPermissions.get(uid); 3935 if (perms != null) { 3936 if (perms.contains(permName)) { 3937 return PackageManager.PERMISSION_GRANTED; 3938 } 3939 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3940 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3941 return PackageManager.PERMISSION_GRANTED; 3942 } 3943 } 3944 } 3945 } 3946 3947 return PackageManager.PERMISSION_DENIED; 3948 } 3949 3950 @Override 3951 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3952 if (UserHandle.getCallingUserId() != userId) { 3953 mContext.enforceCallingPermission( 3954 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3955 "isPermissionRevokedByPolicy for user " + userId); 3956 } 3957 3958 if (checkPermission(permission, packageName, userId) 3959 == PackageManager.PERMISSION_GRANTED) { 3960 return false; 3961 } 3962 3963 final long identity = Binder.clearCallingIdentity(); 3964 try { 3965 final int flags = getPermissionFlags(permission, packageName, userId); 3966 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3967 } finally { 3968 Binder.restoreCallingIdentity(identity); 3969 } 3970 } 3971 3972 @Override 3973 public String getPermissionControllerPackageName() { 3974 synchronized (mPackages) { 3975 return mRequiredInstallerPackage; 3976 } 3977 } 3978 3979 /** 3980 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3981 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3982 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3983 * @param message the message to log on security exception 3984 */ 3985 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3986 boolean checkShell, String message) { 3987 if (userId < 0) { 3988 throw new IllegalArgumentException("Invalid userId " + userId); 3989 } 3990 if (checkShell) { 3991 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3992 } 3993 if (userId == UserHandle.getUserId(callingUid)) return; 3994 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3995 if (requireFullPermission) { 3996 mContext.enforceCallingOrSelfPermission( 3997 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3998 } else { 3999 try { 4000 mContext.enforceCallingOrSelfPermission( 4001 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 4002 } catch (SecurityException se) { 4003 mContext.enforceCallingOrSelfPermission( 4004 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 4005 } 4006 } 4007 } 4008 } 4009 4010 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 4011 if (callingUid == Process.SHELL_UID) { 4012 if (userHandle >= 0 4013 && sUserManager.hasUserRestriction(restriction, userHandle)) { 4014 throw new SecurityException("Shell does not have permission to access user " 4015 + userHandle); 4016 } else if (userHandle < 0) { 4017 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 4018 + Debug.getCallers(3)); 4019 } 4020 } 4021 } 4022 4023 private BasePermission findPermissionTreeLP(String permName) { 4024 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 4025 if (permName.startsWith(bp.name) && 4026 permName.length() > bp.name.length() && 4027 permName.charAt(bp.name.length()) == '.') { 4028 return bp; 4029 } 4030 } 4031 return null; 4032 } 4033 4034 private BasePermission checkPermissionTreeLP(String permName) { 4035 if (permName != null) { 4036 BasePermission bp = findPermissionTreeLP(permName); 4037 if (bp != null) { 4038 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 4039 return bp; 4040 } 4041 throw new SecurityException("Calling uid " 4042 + Binder.getCallingUid() 4043 + " is not allowed to add to permission tree " 4044 + bp.name + " owned by uid " + bp.uid); 4045 } 4046 } 4047 throw new SecurityException("No permission tree found for " + permName); 4048 } 4049 4050 static boolean compareStrings(CharSequence s1, CharSequence s2) { 4051 if (s1 == null) { 4052 return s2 == null; 4053 } 4054 if (s2 == null) { 4055 return false; 4056 } 4057 if (s1.getClass() != s2.getClass()) { 4058 return false; 4059 } 4060 return s1.equals(s2); 4061 } 4062 4063 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 4064 if (pi1.icon != pi2.icon) return false; 4065 if (pi1.logo != pi2.logo) return false; 4066 if (pi1.protectionLevel != pi2.protectionLevel) return false; 4067 if (!compareStrings(pi1.name, pi2.name)) return false; 4068 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 4069 // We'll take care of setting this one. 4070 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 4071 // These are not currently stored in settings. 4072 //if (!compareStrings(pi1.group, pi2.group)) return false; 4073 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 4074 //if (pi1.labelRes != pi2.labelRes) return false; 4075 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 4076 return true; 4077 } 4078 4079 int permissionInfoFootprint(PermissionInfo info) { 4080 int size = info.name.length(); 4081 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 4082 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 4083 return size; 4084 } 4085 4086 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 4087 int size = 0; 4088 for (BasePermission perm : mSettings.mPermissions.values()) { 4089 if (perm.uid == tree.uid) { 4090 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 4091 } 4092 } 4093 return size; 4094 } 4095 4096 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 4097 // We calculate the max size of permissions defined by this uid and throw 4098 // if that plus the size of 'info' would exceed our stated maximum. 4099 if (tree.uid != Process.SYSTEM_UID) { 4100 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 4101 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 4102 throw new SecurityException("Permission tree size cap exceeded"); 4103 } 4104 } 4105 } 4106 4107 boolean addPermissionLocked(PermissionInfo info, boolean async) { 4108 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 4109 throw new SecurityException("Label must be specified in permission"); 4110 } 4111 BasePermission tree = checkPermissionTreeLP(info.name); 4112 BasePermission bp = mSettings.mPermissions.get(info.name); 4113 boolean added = bp == null; 4114 boolean changed = true; 4115 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 4116 if (added) { 4117 enforcePermissionCapLocked(info, tree); 4118 bp = new BasePermission(info.name, tree.sourcePackage, 4119 BasePermission.TYPE_DYNAMIC); 4120 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 4121 throw new SecurityException( 4122 "Not allowed to modify non-dynamic permission " 4123 + info.name); 4124 } else { 4125 if (bp.protectionLevel == fixedLevel 4126 && bp.perm.owner.equals(tree.perm.owner) 4127 && bp.uid == tree.uid 4128 && comparePermissionInfos(bp.perm.info, info)) { 4129 changed = false; 4130 } 4131 } 4132 bp.protectionLevel = fixedLevel; 4133 info = new PermissionInfo(info); 4134 info.protectionLevel = fixedLevel; 4135 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 4136 bp.perm.info.packageName = tree.perm.info.packageName; 4137 bp.uid = tree.uid; 4138 if (added) { 4139 mSettings.mPermissions.put(info.name, bp); 4140 } 4141 if (changed) { 4142 if (!async) { 4143 mSettings.writeLPr(); 4144 } else { 4145 scheduleWriteSettingsLocked(); 4146 } 4147 } 4148 return added; 4149 } 4150 4151 @Override 4152 public boolean addPermission(PermissionInfo info) { 4153 synchronized (mPackages) { 4154 return addPermissionLocked(info, false); 4155 } 4156 } 4157 4158 @Override 4159 public boolean addPermissionAsync(PermissionInfo info) { 4160 synchronized (mPackages) { 4161 return addPermissionLocked(info, true); 4162 } 4163 } 4164 4165 @Override 4166 public void removePermission(String name) { 4167 synchronized (mPackages) { 4168 checkPermissionTreeLP(name); 4169 BasePermission bp = mSettings.mPermissions.get(name); 4170 if (bp != null) { 4171 if (bp.type != BasePermission.TYPE_DYNAMIC) { 4172 throw new SecurityException( 4173 "Not allowed to modify non-dynamic permission " 4174 + name); 4175 } 4176 mSettings.mPermissions.remove(name); 4177 mSettings.writeLPr(); 4178 } 4179 } 4180 } 4181 4182 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 4183 BasePermission bp) { 4184 int index = pkg.requestedPermissions.indexOf(bp.name); 4185 if (index == -1) { 4186 throw new SecurityException("Package " + pkg.packageName 4187 + " has not requested permission " + bp.name); 4188 } 4189 if (!bp.isRuntime() && !bp.isDevelopment()) { 4190 throw new SecurityException("Permission " + bp.name 4191 + " is not a changeable permission type"); 4192 } 4193 } 4194 4195 @Override 4196 public void grantRuntimePermission(String packageName, String name, final int userId) { 4197 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4198 } 4199 4200 private void grantRuntimePermission(String packageName, String name, final int userId, 4201 boolean overridePolicy) { 4202 if (!sUserManager.exists(userId)) { 4203 Log.e(TAG, "No such user:" + userId); 4204 return; 4205 } 4206 4207 mContext.enforceCallingOrSelfPermission( 4208 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 4209 "grantRuntimePermission"); 4210 4211 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4212 true /* requireFullPermission */, true /* checkShell */, 4213 "grantRuntimePermission"); 4214 4215 final int uid; 4216 final SettingBase sb; 4217 4218 synchronized (mPackages) { 4219 final PackageParser.Package pkg = mPackages.get(packageName); 4220 if (pkg == null) { 4221 throw new IllegalArgumentException("Unknown package: " + packageName); 4222 } 4223 4224 final BasePermission bp = mSettings.mPermissions.get(name); 4225 if (bp == null) { 4226 throw new IllegalArgumentException("Unknown permission: " + name); 4227 } 4228 4229 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4230 4231 // If a permission review is required for legacy apps we represent 4232 // their permissions as always granted runtime ones since we need 4233 // to keep the review required permission flag per user while an 4234 // install permission's state is shared across all users. 4235 if (mPermissionReviewRequired 4236 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4237 && bp.isRuntime()) { 4238 return; 4239 } 4240 4241 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 4242 sb = (SettingBase) pkg.mExtras; 4243 if (sb == null) { 4244 throw new IllegalArgumentException("Unknown package: " + packageName); 4245 } 4246 4247 final PermissionsState permissionsState = sb.getPermissionsState(); 4248 4249 final int flags = permissionsState.getPermissionFlags(name, userId); 4250 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4251 throw new SecurityException("Cannot grant system fixed permission " 4252 + name + " for package " + packageName); 4253 } 4254 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4255 throw new SecurityException("Cannot grant policy fixed permission " 4256 + name + " for package " + packageName); 4257 } 4258 4259 if (bp.isDevelopment()) { 4260 // Development permissions must be handled specially, since they are not 4261 // normal runtime permissions. For now they apply to all users. 4262 if (permissionsState.grantInstallPermission(bp) != 4263 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4264 scheduleWriteSettingsLocked(); 4265 } 4266 return; 4267 } 4268 4269 if (pkg.applicationInfo.isEphemeralApp() && !bp.isEphemeral()) { 4270 throw new SecurityException("Cannot grant non-ephemeral permission" 4271 + name + " for package " + packageName); 4272 } 4273 4274 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4275 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4276 return; 4277 } 4278 4279 final int result = permissionsState.grantRuntimePermission(bp, userId); 4280 switch (result) { 4281 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4282 return; 4283 } 4284 4285 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4286 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4287 mHandler.post(new Runnable() { 4288 @Override 4289 public void run() { 4290 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4291 } 4292 }); 4293 } 4294 break; 4295 } 4296 4297 if (bp.isRuntime()) { 4298 logPermissionGranted(mContext, name, packageName); 4299 } 4300 4301 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4302 4303 // Not critical if that is lost - app has to request again. 4304 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4305 } 4306 4307 // Only need to do this if user is initialized. Otherwise it's a new user 4308 // and there are no processes running as the user yet and there's no need 4309 // to make an expensive call to remount processes for the changed permissions. 4310 if (READ_EXTERNAL_STORAGE.equals(name) 4311 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4312 final long token = Binder.clearCallingIdentity(); 4313 try { 4314 if (sUserManager.isInitialized(userId)) { 4315 StorageManagerInternal storageManagerInternal = LocalServices.getService( 4316 StorageManagerInternal.class); 4317 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName); 4318 } 4319 } finally { 4320 Binder.restoreCallingIdentity(token); 4321 } 4322 } 4323 } 4324 4325 @Override 4326 public void revokeRuntimePermission(String packageName, String name, int userId) { 4327 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4328 } 4329 4330 private void revokeRuntimePermission(String packageName, String name, int userId, 4331 boolean overridePolicy) { 4332 if (!sUserManager.exists(userId)) { 4333 Log.e(TAG, "No such user:" + userId); 4334 return; 4335 } 4336 4337 mContext.enforceCallingOrSelfPermission( 4338 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4339 "revokeRuntimePermission"); 4340 4341 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4342 true /* requireFullPermission */, true /* checkShell */, 4343 "revokeRuntimePermission"); 4344 4345 final int appId; 4346 4347 synchronized (mPackages) { 4348 final PackageParser.Package pkg = mPackages.get(packageName); 4349 if (pkg == null) { 4350 throw new IllegalArgumentException("Unknown package: " + packageName); 4351 } 4352 4353 final BasePermission bp = mSettings.mPermissions.get(name); 4354 if (bp == null) { 4355 throw new IllegalArgumentException("Unknown permission: " + name); 4356 } 4357 4358 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4359 4360 // If a permission review is required for legacy apps we represent 4361 // their permissions as always granted runtime ones since we need 4362 // to keep the review required permission flag per user while an 4363 // install permission's state is shared across all users. 4364 if (mPermissionReviewRequired 4365 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4366 && bp.isRuntime()) { 4367 return; 4368 } 4369 4370 SettingBase sb = (SettingBase) pkg.mExtras; 4371 if (sb == null) { 4372 throw new IllegalArgumentException("Unknown package: " + packageName); 4373 } 4374 4375 final PermissionsState permissionsState = sb.getPermissionsState(); 4376 4377 final int flags = permissionsState.getPermissionFlags(name, userId); 4378 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4379 throw new SecurityException("Cannot revoke system fixed permission " 4380 + name + " for package " + packageName); 4381 } 4382 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4383 throw new SecurityException("Cannot revoke policy fixed permission " 4384 + name + " for package " + packageName); 4385 } 4386 4387 if (bp.isDevelopment()) { 4388 // Development permissions must be handled specially, since they are not 4389 // normal runtime permissions. For now they apply to all users. 4390 if (permissionsState.revokeInstallPermission(bp) != 4391 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4392 scheduleWriteSettingsLocked(); 4393 } 4394 return; 4395 } 4396 4397 if (permissionsState.revokeRuntimePermission(bp, userId) == 4398 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4399 return; 4400 } 4401 4402 if (bp.isRuntime()) { 4403 logPermissionRevoked(mContext, name, packageName); 4404 } 4405 4406 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4407 4408 // Critical, after this call app should never have the permission. 4409 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4410 4411 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4412 } 4413 4414 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4415 } 4416 4417 /** 4418 * Get the first event id for the permission. 4419 * 4420 * <p>There are four events for each permission: <ul> 4421 * <li>Request permission: first id + 0</li> 4422 * <li>Grant permission: first id + 1</li> 4423 * <li>Request for permission denied: first id + 2</li> 4424 * <li>Revoke permission: first id + 3</li> 4425 * </ul></p> 4426 * 4427 * @param name name of the permission 4428 * 4429 * @return The first event id for the permission 4430 */ 4431 private static int getBaseEventId(@NonNull String name) { 4432 int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name); 4433 4434 if (eventIdIndex == -1) { 4435 if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE 4436 || "user".equals(Build.TYPE)) { 4437 Log.i(TAG, "Unknown permission " + name); 4438 4439 return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN; 4440 } else { 4441 // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated. 4442 // 4443 // Also update 4444 // - EventLogger#ALL_DANGEROUS_PERMISSIONS 4445 // - metrics_constants.proto 4446 throw new IllegalStateException("Unknown permission " + name); 4447 } 4448 } 4449 4450 return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4; 4451 } 4452 4453 /** 4454 * Log that a permission was revoked. 4455 * 4456 * @param context Context of the caller 4457 * @param name name of the permission 4458 * @param packageName package permission if for 4459 */ 4460 private static void logPermissionRevoked(@NonNull Context context, @NonNull String name, 4461 @NonNull String packageName) { 4462 MetricsLogger.action(context, getBaseEventId(name) + 3, packageName); 4463 } 4464 4465 /** 4466 * Log that a permission request was granted. 4467 * 4468 * @param context Context of the caller 4469 * @param name name of the permission 4470 * @param packageName package permission if for 4471 */ 4472 private static void logPermissionGranted(@NonNull Context context, @NonNull String name, 4473 @NonNull String packageName) { 4474 MetricsLogger.action(context, getBaseEventId(name) + 1, packageName); 4475 } 4476 4477 @Override 4478 public void resetRuntimePermissions() { 4479 mContext.enforceCallingOrSelfPermission( 4480 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4481 "revokeRuntimePermission"); 4482 4483 int callingUid = Binder.getCallingUid(); 4484 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4485 mContext.enforceCallingOrSelfPermission( 4486 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4487 "resetRuntimePermissions"); 4488 } 4489 4490 synchronized (mPackages) { 4491 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4492 for (int userId : UserManagerService.getInstance().getUserIds()) { 4493 final int packageCount = mPackages.size(); 4494 for (int i = 0; i < packageCount; i++) { 4495 PackageParser.Package pkg = mPackages.valueAt(i); 4496 if (!(pkg.mExtras instanceof PackageSetting)) { 4497 continue; 4498 } 4499 PackageSetting ps = (PackageSetting) pkg.mExtras; 4500 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4501 } 4502 } 4503 } 4504 } 4505 4506 @Override 4507 public int getPermissionFlags(String name, String packageName, int userId) { 4508 if (!sUserManager.exists(userId)) { 4509 return 0; 4510 } 4511 4512 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4513 4514 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4515 true /* requireFullPermission */, false /* checkShell */, 4516 "getPermissionFlags"); 4517 4518 synchronized (mPackages) { 4519 final PackageParser.Package pkg = mPackages.get(packageName); 4520 if (pkg == null) { 4521 return 0; 4522 } 4523 4524 final BasePermission bp = mSettings.mPermissions.get(name); 4525 if (bp == null) { 4526 return 0; 4527 } 4528 4529 SettingBase sb = (SettingBase) pkg.mExtras; 4530 if (sb == null) { 4531 return 0; 4532 } 4533 4534 PermissionsState permissionsState = sb.getPermissionsState(); 4535 return permissionsState.getPermissionFlags(name, userId); 4536 } 4537 } 4538 4539 @Override 4540 public void updatePermissionFlags(String name, String packageName, int flagMask, 4541 int flagValues, int userId) { 4542 if (!sUserManager.exists(userId)) { 4543 return; 4544 } 4545 4546 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4547 4548 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4549 true /* requireFullPermission */, true /* checkShell */, 4550 "updatePermissionFlags"); 4551 4552 // Only the system can change these flags and nothing else. 4553 if (getCallingUid() != Process.SYSTEM_UID) { 4554 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4555 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4556 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4557 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4558 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4559 } 4560 4561 synchronized (mPackages) { 4562 final PackageParser.Package pkg = mPackages.get(packageName); 4563 if (pkg == null) { 4564 throw new IllegalArgumentException("Unknown package: " + packageName); 4565 } 4566 4567 final BasePermission bp = mSettings.mPermissions.get(name); 4568 if (bp == null) { 4569 throw new IllegalArgumentException("Unknown permission: " + name); 4570 } 4571 4572 SettingBase sb = (SettingBase) pkg.mExtras; 4573 if (sb == null) { 4574 throw new IllegalArgumentException("Unknown package: " + packageName); 4575 } 4576 4577 PermissionsState permissionsState = sb.getPermissionsState(); 4578 4579 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4580 4581 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4582 // Install and runtime permissions are stored in different places, 4583 // so figure out what permission changed and persist the change. 4584 if (permissionsState.getInstallPermissionState(name) != null) { 4585 scheduleWriteSettingsLocked(); 4586 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4587 || hadState) { 4588 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4589 } 4590 } 4591 } 4592 } 4593 4594 /** 4595 * Update the permission flags for all packages and runtime permissions of a user in order 4596 * to allow device or profile owner to remove POLICY_FIXED. 4597 */ 4598 @Override 4599 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4600 if (!sUserManager.exists(userId)) { 4601 return; 4602 } 4603 4604 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4605 4606 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4607 true /* requireFullPermission */, true /* checkShell */, 4608 "updatePermissionFlagsForAllApps"); 4609 4610 // Only the system can change system fixed flags. 4611 if (getCallingUid() != Process.SYSTEM_UID) { 4612 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4613 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4614 } 4615 4616 synchronized (mPackages) { 4617 boolean changed = false; 4618 final int packageCount = mPackages.size(); 4619 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4620 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4621 SettingBase sb = (SettingBase) pkg.mExtras; 4622 if (sb == null) { 4623 continue; 4624 } 4625 PermissionsState permissionsState = sb.getPermissionsState(); 4626 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4627 userId, flagMask, flagValues); 4628 } 4629 if (changed) { 4630 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4631 } 4632 } 4633 } 4634 4635 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4636 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4637 != PackageManager.PERMISSION_GRANTED 4638 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4639 != PackageManager.PERMISSION_GRANTED) { 4640 throw new SecurityException(message + " requires " 4641 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4642 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4643 } 4644 } 4645 4646 @Override 4647 public boolean shouldShowRequestPermissionRationale(String permissionName, 4648 String packageName, int userId) { 4649 if (UserHandle.getCallingUserId() != userId) { 4650 mContext.enforceCallingPermission( 4651 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4652 "canShowRequestPermissionRationale for user " + userId); 4653 } 4654 4655 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4656 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4657 return false; 4658 } 4659 4660 if (checkPermission(permissionName, packageName, userId) 4661 == PackageManager.PERMISSION_GRANTED) { 4662 return false; 4663 } 4664 4665 final int flags; 4666 4667 final long identity = Binder.clearCallingIdentity(); 4668 try { 4669 flags = getPermissionFlags(permissionName, 4670 packageName, userId); 4671 } finally { 4672 Binder.restoreCallingIdentity(identity); 4673 } 4674 4675 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4676 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4677 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4678 4679 if ((flags & fixedFlags) != 0) { 4680 return false; 4681 } 4682 4683 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4684 } 4685 4686 @Override 4687 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4688 mContext.enforceCallingOrSelfPermission( 4689 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4690 "addOnPermissionsChangeListener"); 4691 4692 synchronized (mPackages) { 4693 mOnPermissionChangeListeners.addListenerLocked(listener); 4694 } 4695 } 4696 4697 @Override 4698 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4699 synchronized (mPackages) { 4700 mOnPermissionChangeListeners.removeListenerLocked(listener); 4701 } 4702 } 4703 4704 @Override 4705 public boolean isProtectedBroadcast(String actionName) { 4706 synchronized (mPackages) { 4707 if (mProtectedBroadcasts.contains(actionName)) { 4708 return true; 4709 } else if (actionName != null) { 4710 // TODO: remove these terrible hacks 4711 if (actionName.startsWith("android.net.netmon.lingerExpired") 4712 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4713 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4714 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4715 return true; 4716 } 4717 } 4718 } 4719 return false; 4720 } 4721 4722 @Override 4723 public int checkSignatures(String pkg1, String pkg2) { 4724 synchronized (mPackages) { 4725 final PackageParser.Package p1 = mPackages.get(pkg1); 4726 final PackageParser.Package p2 = mPackages.get(pkg2); 4727 if (p1 == null || p1.mExtras == null 4728 || p2 == null || p2.mExtras == null) { 4729 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4730 } 4731 return compareSignatures(p1.mSignatures, p2.mSignatures); 4732 } 4733 } 4734 4735 @Override 4736 public int checkUidSignatures(int uid1, int uid2) { 4737 // Map to base uids. 4738 uid1 = UserHandle.getAppId(uid1); 4739 uid2 = UserHandle.getAppId(uid2); 4740 // reader 4741 synchronized (mPackages) { 4742 Signature[] s1; 4743 Signature[] s2; 4744 Object obj = mSettings.getUserIdLPr(uid1); 4745 if (obj != null) { 4746 if (obj instanceof SharedUserSetting) { 4747 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4748 } else if (obj instanceof PackageSetting) { 4749 s1 = ((PackageSetting)obj).signatures.mSignatures; 4750 } else { 4751 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4752 } 4753 } else { 4754 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4755 } 4756 obj = mSettings.getUserIdLPr(uid2); 4757 if (obj != null) { 4758 if (obj instanceof SharedUserSetting) { 4759 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4760 } else if (obj instanceof PackageSetting) { 4761 s2 = ((PackageSetting)obj).signatures.mSignatures; 4762 } else { 4763 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4764 } 4765 } else { 4766 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4767 } 4768 return compareSignatures(s1, s2); 4769 } 4770 } 4771 4772 /** 4773 * This method should typically only be used when granting or revoking 4774 * permissions, since the app may immediately restart after this call. 4775 * <p> 4776 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 4777 * guard your work against the app being relaunched. 4778 */ 4779 private void killUid(int appId, int userId, String reason) { 4780 final long identity = Binder.clearCallingIdentity(); 4781 try { 4782 IActivityManager am = ActivityManager.getService(); 4783 if (am != null) { 4784 try { 4785 am.killUid(appId, userId, reason); 4786 } catch (RemoteException e) { 4787 /* ignore - same process */ 4788 } 4789 } 4790 } finally { 4791 Binder.restoreCallingIdentity(identity); 4792 } 4793 } 4794 4795 /** 4796 * Compares two sets of signatures. Returns: 4797 * <br /> 4798 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4799 * <br /> 4800 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4801 * <br /> 4802 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4803 * <br /> 4804 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4805 * <br /> 4806 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4807 */ 4808 static int compareSignatures(Signature[] s1, Signature[] s2) { 4809 if (s1 == null) { 4810 return s2 == null 4811 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4812 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4813 } 4814 4815 if (s2 == null) { 4816 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4817 } 4818 4819 if (s1.length != s2.length) { 4820 return PackageManager.SIGNATURE_NO_MATCH; 4821 } 4822 4823 // Since both signature sets are of size 1, we can compare without HashSets. 4824 if (s1.length == 1) { 4825 return s1[0].equals(s2[0]) ? 4826 PackageManager.SIGNATURE_MATCH : 4827 PackageManager.SIGNATURE_NO_MATCH; 4828 } 4829 4830 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4831 for (Signature sig : s1) { 4832 set1.add(sig); 4833 } 4834 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4835 for (Signature sig : s2) { 4836 set2.add(sig); 4837 } 4838 // Make sure s2 contains all signatures in s1. 4839 if (set1.equals(set2)) { 4840 return PackageManager.SIGNATURE_MATCH; 4841 } 4842 return PackageManager.SIGNATURE_NO_MATCH; 4843 } 4844 4845 /** 4846 * If the database version for this type of package (internal storage or 4847 * external storage) is less than the version where package signatures 4848 * were updated, return true. 4849 */ 4850 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4851 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4852 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4853 } 4854 4855 /** 4856 * Used for backward compatibility to make sure any packages with 4857 * certificate chains get upgraded to the new style. {@code existingSigs} 4858 * will be in the old format (since they were stored on disk from before the 4859 * system upgrade) and {@code scannedSigs} will be in the newer format. 4860 */ 4861 private int compareSignaturesCompat(PackageSignatures existingSigs, 4862 PackageParser.Package scannedPkg) { 4863 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4864 return PackageManager.SIGNATURE_NO_MATCH; 4865 } 4866 4867 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4868 for (Signature sig : existingSigs.mSignatures) { 4869 existingSet.add(sig); 4870 } 4871 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4872 for (Signature sig : scannedPkg.mSignatures) { 4873 try { 4874 Signature[] chainSignatures = sig.getChainSignatures(); 4875 for (Signature chainSig : chainSignatures) { 4876 scannedCompatSet.add(chainSig); 4877 } 4878 } catch (CertificateEncodingException e) { 4879 scannedCompatSet.add(sig); 4880 } 4881 } 4882 /* 4883 * Make sure the expanded scanned set contains all signatures in the 4884 * existing one. 4885 */ 4886 if (scannedCompatSet.equals(existingSet)) { 4887 // Migrate the old signatures to the new scheme. 4888 existingSigs.assignSignatures(scannedPkg.mSignatures); 4889 // The new KeySets will be re-added later in the scanning process. 4890 synchronized (mPackages) { 4891 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4892 } 4893 return PackageManager.SIGNATURE_MATCH; 4894 } 4895 return PackageManager.SIGNATURE_NO_MATCH; 4896 } 4897 4898 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4899 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4900 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4901 } 4902 4903 private int compareSignaturesRecover(PackageSignatures existingSigs, 4904 PackageParser.Package scannedPkg) { 4905 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4906 return PackageManager.SIGNATURE_NO_MATCH; 4907 } 4908 4909 String msg = null; 4910 try { 4911 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4912 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4913 + scannedPkg.packageName); 4914 return PackageManager.SIGNATURE_MATCH; 4915 } 4916 } catch (CertificateException e) { 4917 msg = e.getMessage(); 4918 } 4919 4920 logCriticalInfo(Log.INFO, 4921 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4922 return PackageManager.SIGNATURE_NO_MATCH; 4923 } 4924 4925 @Override 4926 public List<String> getAllPackages() { 4927 synchronized (mPackages) { 4928 return new ArrayList<String>(mPackages.keySet()); 4929 } 4930 } 4931 4932 @Override 4933 public String[] getPackagesForUid(int uid) { 4934 final int userId = UserHandle.getUserId(uid); 4935 uid = UserHandle.getAppId(uid); 4936 // reader 4937 synchronized (mPackages) { 4938 Object obj = mSettings.getUserIdLPr(uid); 4939 if (obj instanceof SharedUserSetting) { 4940 final SharedUserSetting sus = (SharedUserSetting) obj; 4941 final int N = sus.packages.size(); 4942 String[] res = new String[N]; 4943 final Iterator<PackageSetting> it = sus.packages.iterator(); 4944 int i = 0; 4945 while (it.hasNext()) { 4946 PackageSetting ps = it.next(); 4947 if (ps.getInstalled(userId)) { 4948 res[i++] = ps.name; 4949 } else { 4950 res = ArrayUtils.removeElement(String.class, res, res[i]); 4951 } 4952 } 4953 return res; 4954 } else if (obj instanceof PackageSetting) { 4955 final PackageSetting ps = (PackageSetting) obj; 4956 return new String[] { ps.name }; 4957 } 4958 } 4959 return null; 4960 } 4961 4962 @Override 4963 public String getNameForUid(int uid) { 4964 // reader 4965 synchronized (mPackages) { 4966 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4967 if (obj instanceof SharedUserSetting) { 4968 final SharedUserSetting sus = (SharedUserSetting) obj; 4969 return sus.name + ":" + sus.userId; 4970 } else if (obj instanceof PackageSetting) { 4971 final PackageSetting ps = (PackageSetting) obj; 4972 return ps.name; 4973 } 4974 } 4975 return null; 4976 } 4977 4978 @Override 4979 public int getUidForSharedUser(String sharedUserName) { 4980 if(sharedUserName == null) { 4981 return -1; 4982 } 4983 // reader 4984 synchronized (mPackages) { 4985 SharedUserSetting suid; 4986 try { 4987 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4988 if (suid != null) { 4989 return suid.userId; 4990 } 4991 } catch (PackageManagerException ignore) { 4992 // can't happen, but, still need to catch it 4993 } 4994 return -1; 4995 } 4996 } 4997 4998 @Override 4999 public int getFlagsForUid(int uid) { 5000 synchronized (mPackages) { 5001 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5002 if (obj instanceof SharedUserSetting) { 5003 final SharedUserSetting sus = (SharedUserSetting) obj; 5004 return sus.pkgFlags; 5005 } else if (obj instanceof PackageSetting) { 5006 final PackageSetting ps = (PackageSetting) obj; 5007 return ps.pkgFlags; 5008 } 5009 } 5010 return 0; 5011 } 5012 5013 @Override 5014 public int getPrivateFlagsForUid(int uid) { 5015 synchronized (mPackages) { 5016 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 5017 if (obj instanceof SharedUserSetting) { 5018 final SharedUserSetting sus = (SharedUserSetting) obj; 5019 return sus.pkgPrivateFlags; 5020 } else if (obj instanceof PackageSetting) { 5021 final PackageSetting ps = (PackageSetting) obj; 5022 return ps.pkgPrivateFlags; 5023 } 5024 } 5025 return 0; 5026 } 5027 5028 @Override 5029 public boolean isUidPrivileged(int uid) { 5030 uid = UserHandle.getAppId(uid); 5031 // reader 5032 synchronized (mPackages) { 5033 Object obj = mSettings.getUserIdLPr(uid); 5034 if (obj instanceof SharedUserSetting) { 5035 final SharedUserSetting sus = (SharedUserSetting) obj; 5036 final Iterator<PackageSetting> it = sus.packages.iterator(); 5037 while (it.hasNext()) { 5038 if (it.next().isPrivileged()) { 5039 return true; 5040 } 5041 } 5042 } else if (obj instanceof PackageSetting) { 5043 final PackageSetting ps = (PackageSetting) obj; 5044 return ps.isPrivileged(); 5045 } 5046 } 5047 return false; 5048 } 5049 5050 @Override 5051 public String[] getAppOpPermissionPackages(String permissionName) { 5052 synchronized (mPackages) { 5053 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 5054 if (pkgs == null) { 5055 return null; 5056 } 5057 return pkgs.toArray(new String[pkgs.size()]); 5058 } 5059 } 5060 5061 @Override 5062 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 5063 int flags, int userId) { 5064 try { 5065 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 5066 5067 if (!sUserManager.exists(userId)) return null; 5068 flags = updateFlagsForResolve(flags, userId, intent); 5069 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5070 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 5071 5072 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5073 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 5074 flags, userId); 5075 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5076 5077 final ResolveInfo bestChoice = 5078 chooseBestActivity(intent, resolvedType, flags, query, userId); 5079 return bestChoice; 5080 } finally { 5081 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5082 } 5083 } 5084 5085 @Override 5086 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 5087 IntentFilter filter, int match, ComponentName activity) { 5088 final int userId = UserHandle.getCallingUserId(); 5089 if (DEBUG_PREFERRED) { 5090 Log.v(TAG, "setLastChosenActivity intent=" + intent 5091 + " resolvedType=" + resolvedType 5092 + " flags=" + flags 5093 + " filter=" + filter 5094 + " match=" + match 5095 + " activity=" + activity); 5096 filter.dump(new PrintStreamPrinter(System.out), " "); 5097 } 5098 intent.setComponent(null); 5099 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5100 userId); 5101 // Find any earlier preferred or last chosen entries and nuke them 5102 findPreferredActivity(intent, resolvedType, 5103 flags, query, 0, false, true, false, userId); 5104 // Add the new activity as the last chosen for this filter 5105 addPreferredActivityInternal(filter, match, null, activity, false, userId, 5106 "Setting last chosen"); 5107 } 5108 5109 @Override 5110 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 5111 final int userId = UserHandle.getCallingUserId(); 5112 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 5113 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 5114 userId); 5115 return findPreferredActivity(intent, resolvedType, flags, query, 0, 5116 false, false, false, userId); 5117 } 5118 5119 private boolean isEphemeralDisabled() { 5120 // ephemeral apps have been disabled across the board 5121 if (DISABLE_EPHEMERAL_APPS) { 5122 return true; 5123 } 5124 // system isn't up yet; can't read settings, so, assume no ephemeral apps 5125 if (!mSystemReady) { 5126 return true; 5127 } 5128 // we can't get a content resolver until the system is ready; these checks must happen last 5129 final ContentResolver resolver = mContext.getContentResolver(); 5130 if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) { 5131 return true; 5132 } 5133 return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0; 5134 } 5135 5136 private boolean isEphemeralAllowed( 5137 Intent intent, List<ResolveInfo> resolvedActivities, int userId, 5138 boolean skipPackageCheck) { 5139 // Short circuit and return early if possible. 5140 if (isEphemeralDisabled()) { 5141 return false; 5142 } 5143 final int callingUser = UserHandle.getCallingUserId(); 5144 if (callingUser != UserHandle.USER_SYSTEM) { 5145 return false; 5146 } 5147 if (mEphemeralResolverConnection == null) { 5148 return false; 5149 } 5150 if (mEphemeralInstallerComponent == null) { 5151 return false; 5152 } 5153 if (intent.getComponent() != null) { 5154 return false; 5155 } 5156 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) { 5157 return false; 5158 } 5159 if (!skipPackageCheck && intent.getPackage() != null) { 5160 return false; 5161 } 5162 final boolean isWebUri = hasWebURI(intent); 5163 if (!isWebUri || intent.getData().getHost() == null) { 5164 return false; 5165 } 5166 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 5167 synchronized (mPackages) { 5168 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); 5169 for (int n = 0; n < count; n++) { 5170 ResolveInfo info = resolvedActivities.get(n); 5171 String packageName = info.activityInfo.packageName; 5172 PackageSetting ps = mSettings.mPackages.get(packageName); 5173 if (ps != null) { 5174 // Try to get the status from User settings first 5175 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5176 int status = (int) (packedStatus >> 32); 5177 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 5178 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5179 if (DEBUG_EPHEMERAL) { 5180 Slog.v(TAG, "DENY ephemeral apps;" 5181 + " pkg: " + packageName + ", status: " + status); 5182 } 5183 return false; 5184 } 5185 } 5186 } 5187 } 5188 // We've exhausted all ways to deny ephemeral application; let the system look for them. 5189 return true; 5190 } 5191 5192 private void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj, 5193 Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage, 5194 int userId) { 5195 final Message msg = mHandler.obtainMessage(EPHEMERAL_RESOLUTION_PHASE_TWO, 5196 new EphemeralRequest(responseObj, origIntent, resolvedType, launchIntent, 5197 callingPackage, userId)); 5198 mHandler.sendMessage(msg); 5199 } 5200 5201 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 5202 int flags, List<ResolveInfo> query, int userId) { 5203 if (query != null) { 5204 final int N = query.size(); 5205 if (N == 1) { 5206 return query.get(0); 5207 } else if (N > 1) { 5208 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 5209 // If there is more than one activity with the same priority, 5210 // then let the user decide between them. 5211 ResolveInfo r0 = query.get(0); 5212 ResolveInfo r1 = query.get(1); 5213 if (DEBUG_INTENT_MATCHING || debug) { 5214 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 5215 + r1.activityInfo.name + "=" + r1.priority); 5216 } 5217 // If the first activity has a higher priority, or a different 5218 // default, then it is always desirable to pick it. 5219 if (r0.priority != r1.priority 5220 || r0.preferredOrder != r1.preferredOrder 5221 || r0.isDefault != r1.isDefault) { 5222 return query.get(0); 5223 } 5224 // If we have saved a preference for a preferred activity for 5225 // this Intent, use that. 5226 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 5227 flags, query, r0.priority, true, false, debug, userId); 5228 if (ri != null) { 5229 return ri; 5230 } 5231 ri = new ResolveInfo(mResolveInfo); 5232 ri.activityInfo = new ActivityInfo(ri.activityInfo); 5233 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 5234 // If all of the options come from the same package, show the application's 5235 // label and icon instead of the generic resolver's. 5236 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 5237 // and then throw away the ResolveInfo itself, meaning that the caller loses 5238 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 5239 // a fallback for this case; we only set the target package's resources on 5240 // the ResolveInfo, not the ActivityInfo. 5241 final String intentPackage = intent.getPackage(); 5242 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 5243 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 5244 ri.resolvePackageName = intentPackage; 5245 if (userNeedsBadging(userId)) { 5246 ri.noResourceId = true; 5247 } else { 5248 ri.icon = appi.icon; 5249 } 5250 ri.iconResourceId = appi.icon; 5251 ri.labelRes = appi.labelRes; 5252 } 5253 ri.activityInfo.applicationInfo = new ApplicationInfo( 5254 ri.activityInfo.applicationInfo); 5255 if (userId != 0) { 5256 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 5257 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 5258 } 5259 // Make sure that the resolver is displayable in car mode 5260 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 5261 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 5262 return ri; 5263 } 5264 } 5265 return null; 5266 } 5267 5268 /** 5269 * Return true if the given list is not empty and all of its contents have 5270 * an activityInfo with the given package name. 5271 */ 5272 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 5273 if (ArrayUtils.isEmpty(list)) { 5274 return false; 5275 } 5276 for (int i = 0, N = list.size(); i < N; i++) { 5277 final ResolveInfo ri = list.get(i); 5278 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 5279 if (ai == null || !packageName.equals(ai.packageName)) { 5280 return false; 5281 } 5282 } 5283 return true; 5284 } 5285 5286 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 5287 int flags, List<ResolveInfo> query, boolean debug, int userId) { 5288 final int N = query.size(); 5289 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 5290 .get(userId); 5291 // Get the list of persistent preferred activities that handle the intent 5292 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 5293 List<PersistentPreferredActivity> pprefs = ppir != null 5294 ? ppir.queryIntent(intent, resolvedType, 5295 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5296 (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, 5297 (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId) 5298 : null; 5299 if (pprefs != null && pprefs.size() > 0) { 5300 final int M = pprefs.size(); 5301 for (int i=0; i<M; i++) { 5302 final PersistentPreferredActivity ppa = pprefs.get(i); 5303 if (DEBUG_PREFERRED || debug) { 5304 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 5305 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 5306 + "\n component=" + ppa.mComponent); 5307 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5308 } 5309 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 5310 flags | MATCH_DISABLED_COMPONENTS, userId); 5311 if (DEBUG_PREFERRED || debug) { 5312 Slog.v(TAG, "Found persistent preferred activity:"); 5313 if (ai != null) { 5314 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5315 } else { 5316 Slog.v(TAG, " null"); 5317 } 5318 } 5319 if (ai == null) { 5320 // This previously registered persistent preferred activity 5321 // component is no longer known. Ignore it and do NOT remove it. 5322 continue; 5323 } 5324 for (int j=0; j<N; j++) { 5325 final ResolveInfo ri = query.get(j); 5326 if (!ri.activityInfo.applicationInfo.packageName 5327 .equals(ai.applicationInfo.packageName)) { 5328 continue; 5329 } 5330 if (!ri.activityInfo.name.equals(ai.name)) { 5331 continue; 5332 } 5333 // Found a persistent preference that can handle the intent. 5334 if (DEBUG_PREFERRED || debug) { 5335 Slog.v(TAG, "Returning persistent preferred activity: " + 5336 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5337 } 5338 return ri; 5339 } 5340 } 5341 } 5342 return null; 5343 } 5344 5345 // TODO: handle preferred activities missing while user has amnesia 5346 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5347 List<ResolveInfo> query, int priority, boolean always, 5348 boolean removeMatches, boolean debug, int userId) { 5349 if (!sUserManager.exists(userId)) return null; 5350 flags = updateFlagsForResolve(flags, userId, intent); 5351 // writer 5352 synchronized (mPackages) { 5353 if (intent.getSelector() != null) { 5354 intent = intent.getSelector(); 5355 } 5356 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 5357 5358 // Try to find a matching persistent preferred activity. 5359 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5360 debug, userId); 5361 5362 // If a persistent preferred activity matched, use it. 5363 if (pri != null) { 5364 return pri; 5365 } 5366 5367 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5368 // Get the list of preferred activities that handle the intent 5369 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5370 List<PreferredActivity> prefs = pir != null 5371 ? pir.queryIntent(intent, resolvedType, 5372 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 5373 (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, 5374 (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId) 5375 : null; 5376 if (prefs != null && prefs.size() > 0) { 5377 boolean changed = false; 5378 try { 5379 // First figure out how good the original match set is. 5380 // We will only allow preferred activities that came 5381 // from the same match quality. 5382 int match = 0; 5383 5384 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5385 5386 final int N = query.size(); 5387 for (int j=0; j<N; j++) { 5388 final ResolveInfo ri = query.get(j); 5389 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 5390 + ": 0x" + Integer.toHexString(match)); 5391 if (ri.match > match) { 5392 match = ri.match; 5393 } 5394 } 5395 5396 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 5397 + Integer.toHexString(match)); 5398 5399 match &= IntentFilter.MATCH_CATEGORY_MASK; 5400 final int M = prefs.size(); 5401 for (int i=0; i<M; i++) { 5402 final PreferredActivity pa = prefs.get(i); 5403 if (DEBUG_PREFERRED || debug) { 5404 Slog.v(TAG, "Checking PreferredActivity ds=" 5405 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5406 + "\n component=" + pa.mPref.mComponent); 5407 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5408 } 5409 if (pa.mPref.mMatch != match) { 5410 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5411 + Integer.toHexString(pa.mPref.mMatch)); 5412 continue; 5413 } 5414 // If it's not an "always" type preferred activity and that's what we're 5415 // looking for, skip it. 5416 if (always && !pa.mPref.mAlways) { 5417 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5418 continue; 5419 } 5420 final ActivityInfo ai = getActivityInfo( 5421 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5422 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5423 userId); 5424 if (DEBUG_PREFERRED || debug) { 5425 Slog.v(TAG, "Found preferred activity:"); 5426 if (ai != null) { 5427 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5428 } else { 5429 Slog.v(TAG, " null"); 5430 } 5431 } 5432 if (ai == null) { 5433 // This previously registered preferred activity 5434 // component is no longer known. Most likely an update 5435 // to the app was installed and in the new version this 5436 // component no longer exists. Clean it up by removing 5437 // it from the preferred activities list, and skip it. 5438 Slog.w(TAG, "Removing dangling preferred activity: " 5439 + pa.mPref.mComponent); 5440 pir.removeFilter(pa); 5441 changed = true; 5442 continue; 5443 } 5444 for (int j=0; j<N; j++) { 5445 final ResolveInfo ri = query.get(j); 5446 if (!ri.activityInfo.applicationInfo.packageName 5447 .equals(ai.applicationInfo.packageName)) { 5448 continue; 5449 } 5450 if (!ri.activityInfo.name.equals(ai.name)) { 5451 continue; 5452 } 5453 5454 if (removeMatches) { 5455 pir.removeFilter(pa); 5456 changed = true; 5457 if (DEBUG_PREFERRED) { 5458 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 5459 } 5460 break; 5461 } 5462 5463 // Okay we found a previously set preferred or last chosen app. 5464 // If the result set is different from when this 5465 // was created, we need to clear it and re-ask the 5466 // user their preference, if we're looking for an "always" type entry. 5467 if (always && !pa.mPref.sameSet(query)) { 5468 Slog.i(TAG, "Result set changed, dropping preferred activity for " 5469 + intent + " type " + resolvedType); 5470 if (DEBUG_PREFERRED) { 5471 Slog.v(TAG, "Removing preferred activity since set changed " 5472 + pa.mPref.mComponent); 5473 } 5474 pir.removeFilter(pa); 5475 // Re-add the filter as a "last chosen" entry (!always) 5476 PreferredActivity lastChosen = new PreferredActivity( 5477 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 5478 pir.addFilter(lastChosen); 5479 changed = true; 5480 return null; 5481 } 5482 5483 // Yay! Either the set matched or we're looking for the last chosen 5484 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5485 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5486 return ri; 5487 } 5488 } 5489 } finally { 5490 if (changed) { 5491 if (DEBUG_PREFERRED) { 5492 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5493 } 5494 scheduleWritePackageRestrictionsLocked(userId); 5495 } 5496 } 5497 } 5498 } 5499 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5500 return null; 5501 } 5502 5503 /* 5504 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5505 */ 5506 @Override 5507 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5508 int targetUserId) { 5509 mContext.enforceCallingOrSelfPermission( 5510 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5511 List<CrossProfileIntentFilter> matches = 5512 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5513 if (matches != null) { 5514 int size = matches.size(); 5515 for (int i = 0; i < size; i++) { 5516 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5517 } 5518 } 5519 if (hasWebURI(intent)) { 5520 // cross-profile app linking works only towards the parent. 5521 final UserInfo parent = getProfileParent(sourceUserId); 5522 synchronized(mPackages) { 5523 int flags = updateFlagsForResolve(0, parent.id, intent); 5524 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5525 intent, resolvedType, flags, sourceUserId, parent.id); 5526 return xpDomainInfo != null; 5527 } 5528 } 5529 return false; 5530 } 5531 5532 private UserInfo getProfileParent(int userId) { 5533 final long identity = Binder.clearCallingIdentity(); 5534 try { 5535 return sUserManager.getProfileParent(userId); 5536 } finally { 5537 Binder.restoreCallingIdentity(identity); 5538 } 5539 } 5540 5541 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5542 String resolvedType, int userId) { 5543 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5544 if (resolver != null) { 5545 return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, 5546 false /*visibleToEphemeral*/, false /*isEphemeral*/, userId); 5547 } 5548 return null; 5549 } 5550 5551 @Override 5552 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5553 String resolvedType, int flags, int userId) { 5554 try { 5555 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5556 5557 return new ParceledListSlice<>( 5558 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5559 } finally { 5560 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5561 } 5562 } 5563 5564 /** 5565 * Returns the package name of the calling Uid if it's an ephemeral app. If it isn't 5566 * ephemeral, returns {@code null}. 5567 */ 5568 private String getEphemeralPackageName(int callingUid) { 5569 final int appId = UserHandle.getAppId(callingUid); 5570 synchronized (mPackages) { 5571 final Object obj = mSettings.getUserIdLPr(appId); 5572 if (obj instanceof PackageSetting) { 5573 final PackageSetting ps = (PackageSetting) obj; 5574 return ps.pkg.applicationInfo.isEphemeralApp() ? ps.pkg.packageName : null; 5575 } 5576 } 5577 return null; 5578 } 5579 5580 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5581 String resolvedType, int flags, int userId) { 5582 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5583 final String ephemeralPkgName = getEphemeralPackageName(Binder.getCallingUid()); 5584 flags = updateFlagsForResolve(flags, userId, intent); 5585 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5586 false /* requireFullPermission */, false /* checkShell */, 5587 "query intent activities"); 5588 ComponentName comp = intent.getComponent(); 5589 if (comp == null) { 5590 if (intent.getSelector() != null) { 5591 intent = intent.getSelector(); 5592 comp = intent.getComponent(); 5593 } 5594 } 5595 5596 if (comp != null) { 5597 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5598 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5599 if (ai != null) { 5600 // When specifying an explicit component, we prevent the activity from being 5601 // used when either 1) the calling package is normal and the activity is within 5602 // an ephemeral application or 2) the calling package is ephemeral and the 5603 // activity is not visible to ephemeral applications. 5604 boolean blockResolution = 5605 (ephemeralPkgName == null 5606 && (ai.applicationInfo.privateFlags 5607 & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0) 5608 || (ephemeralPkgName != null 5609 && (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0); 5610 if (!blockResolution) { 5611 final ResolveInfo ri = new ResolveInfo(); 5612 ri.activityInfo = ai; 5613 list.add(ri); 5614 } 5615 } 5616 return list; 5617 } 5618 5619 // reader 5620 boolean sortResult = false; 5621 boolean addEphemeral = false; 5622 List<ResolveInfo> result; 5623 final String pkgName = intent.getPackage(); 5624 synchronized (mPackages) { 5625 if (pkgName == null) { 5626 List<CrossProfileIntentFilter> matchingFilters = 5627 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5628 // Check for results that need to skip the current profile. 5629 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5630 resolvedType, flags, userId); 5631 if (xpResolveInfo != null) { 5632 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); 5633 xpResult.add(xpResolveInfo); 5634 return filterForEphemeral( 5635 filterIfNotSystemUser(xpResult, userId), ephemeralPkgName); 5636 } 5637 5638 // Check for results in the current profile. 5639 result = filterIfNotSystemUser(mActivities.queryIntent( 5640 intent, resolvedType, flags, userId), userId); 5641 addEphemeral = 5642 isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); 5643 5644 // Check for cross profile results. 5645 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5646 xpResolveInfo = queryCrossProfileIntents( 5647 matchingFilters, intent, resolvedType, flags, userId, 5648 hasNonNegativePriorityResult); 5649 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5650 boolean isVisibleToUser = filterIfNotSystemUser( 5651 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5652 if (isVisibleToUser) { 5653 result.add(xpResolveInfo); 5654 sortResult = true; 5655 } 5656 } 5657 if (hasWebURI(intent)) { 5658 CrossProfileDomainInfo xpDomainInfo = null; 5659 final UserInfo parent = getProfileParent(userId); 5660 if (parent != null) { 5661 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5662 flags, userId, parent.id); 5663 } 5664 if (xpDomainInfo != null) { 5665 if (xpResolveInfo != null) { 5666 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5667 // in the result. 5668 result.remove(xpResolveInfo); 5669 } 5670 if (result.size() == 0 && !addEphemeral) { 5671 // No result in current profile, but found candidate in parent user. 5672 // And we are not going to add emphemeral app, so we can return the 5673 // result straight away. 5674 result.add(xpDomainInfo.resolveInfo); 5675 return filterForEphemeral(result, ephemeralPkgName); 5676 } 5677 } else if (result.size() <= 1 && !addEphemeral) { 5678 // No result in parent user and <= 1 result in current profile, and we 5679 // are not going to add emphemeral app, so we can return the result without 5680 // further processing. 5681 return filterForEphemeral(result, ephemeralPkgName); 5682 } 5683 // We have more than one candidate (combining results from current and parent 5684 // profile), so we need filtering and sorting. 5685 result = filterCandidatesWithDomainPreferredActivitiesLPr( 5686 intent, flags, result, xpDomainInfo, userId); 5687 sortResult = true; 5688 } 5689 } else { 5690 final PackageParser.Package pkg = mPackages.get(pkgName); 5691 if (pkg != null) { 5692 result = filterForEphemeral(filterIfNotSystemUser( 5693 mActivities.queryIntentForPackage( 5694 intent, resolvedType, flags, pkg.activities, userId), 5695 userId), ephemeralPkgName); 5696 } else { 5697 // the caller wants to resolve for a particular package; however, there 5698 // were no installed results, so, try to find an ephemeral result 5699 addEphemeral = isEphemeralAllowed( 5700 intent, null /*result*/, userId, true /*skipPackageCheck*/); 5701 result = new ArrayList<ResolveInfo>(); 5702 } 5703 } 5704 } 5705 if (addEphemeral) { 5706 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 5707 final EphemeralRequest requestObject = new EphemeralRequest( 5708 null /*responseObj*/, intent /*origIntent*/, resolvedType, 5709 null /*launchIntent*/, null /*callingPackage*/, userId); 5710 final EphemeralResponse intentInfo = EphemeralResolver.doEphemeralResolutionPhaseOne( 5711 mContext, mEphemeralResolverConnection, requestObject); 5712 if (intentInfo != null) { 5713 if (DEBUG_EPHEMERAL) { 5714 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 5715 } 5716 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo); 5717 ephemeralInstaller.ephemeralResponse = intentInfo; 5718 // make sure this resolver is the default 5719 ephemeralInstaller.isDefault = true; 5720 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 5721 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 5722 // add a non-generic filter 5723 ephemeralInstaller.filter = new IntentFilter(intent.getAction()); 5724 ephemeralInstaller.filter.addDataPath( 5725 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL); 5726 result.add(ephemeralInstaller); 5727 } 5728 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5729 } 5730 if (sortResult) { 5731 Collections.sort(result, mResolvePrioritySorter); 5732 } 5733 return filterForEphemeral(result, ephemeralPkgName); 5734 } 5735 5736 private static class CrossProfileDomainInfo { 5737 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5738 ResolveInfo resolveInfo; 5739 /* Best domain verification status of the activities found in the other profile */ 5740 int bestDomainVerificationStatus; 5741 } 5742 5743 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5744 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5745 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5746 sourceUserId)) { 5747 return null; 5748 } 5749 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5750 resolvedType, flags, parentUserId); 5751 5752 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5753 return null; 5754 } 5755 CrossProfileDomainInfo result = null; 5756 int size = resultTargetUser.size(); 5757 for (int i = 0; i < size; i++) { 5758 ResolveInfo riTargetUser = resultTargetUser.get(i); 5759 // Intent filter verification is only for filters that specify a host. So don't return 5760 // those that handle all web uris. 5761 if (riTargetUser.handleAllWebDataURI) { 5762 continue; 5763 } 5764 String packageName = riTargetUser.activityInfo.packageName; 5765 PackageSetting ps = mSettings.mPackages.get(packageName); 5766 if (ps == null) { 5767 continue; 5768 } 5769 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5770 int status = (int)(verificationState >> 32); 5771 if (result == null) { 5772 result = new CrossProfileDomainInfo(); 5773 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5774 sourceUserId, parentUserId); 5775 result.bestDomainVerificationStatus = status; 5776 } else { 5777 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5778 result.bestDomainVerificationStatus); 5779 } 5780 } 5781 // Don't consider matches with status NEVER across profiles. 5782 if (result != null && result.bestDomainVerificationStatus 5783 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5784 return null; 5785 } 5786 return result; 5787 } 5788 5789 /** 5790 * Verification statuses are ordered from the worse to the best, except for 5791 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5792 */ 5793 private int bestDomainVerificationStatus(int status1, int status2) { 5794 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5795 return status2; 5796 } 5797 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5798 return status1; 5799 } 5800 return (int) MathUtils.max(status1, status2); 5801 } 5802 5803 private boolean isUserEnabled(int userId) { 5804 long callingId = Binder.clearCallingIdentity(); 5805 try { 5806 UserInfo userInfo = sUserManager.getUserInfo(userId); 5807 return userInfo != null && userInfo.isEnabled(); 5808 } finally { 5809 Binder.restoreCallingIdentity(callingId); 5810 } 5811 } 5812 5813 /** 5814 * Filter out activities with systemUserOnly flag set, when current user is not System. 5815 * 5816 * @return filtered list 5817 */ 5818 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5819 if (userId == UserHandle.USER_SYSTEM) { 5820 return resolveInfos; 5821 } 5822 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5823 ResolveInfo info = resolveInfos.get(i); 5824 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5825 resolveInfos.remove(i); 5826 } 5827 } 5828 return resolveInfos; 5829 } 5830 5831 /** 5832 * Filters out ephemeral activities. 5833 * <p>When resolving for an ephemeral app, only activities that 1) are defined in the 5834 * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned. 5835 * 5836 * @param resolveInfos The pre-filtered list of resolved activities 5837 * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering 5838 * is performed. 5839 * @return A filtered list of resolved activities. 5840 */ 5841 private List<ResolveInfo> filterForEphemeral(List<ResolveInfo> resolveInfos, 5842 String ephemeralPkgName) { 5843 if (ephemeralPkgName == null) { 5844 return resolveInfos; 5845 } 5846 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5847 ResolveInfo info = resolveInfos.get(i); 5848 final boolean isEphemeralApp = info.activityInfo.applicationInfo.isEphemeralApp(); 5849 // allow activities that are defined in the provided package 5850 if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) { 5851 continue; 5852 } 5853 // allow activities that have been explicitly exposed to ephemeral apps 5854 if (!isEphemeralApp 5855 && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) { 5856 continue; 5857 } 5858 resolveInfos.remove(i); 5859 } 5860 return resolveInfos; 5861 } 5862 5863 /** 5864 * @param resolveInfos list of resolve infos in descending priority order 5865 * @return if the list contains a resolve info with non-negative priority 5866 */ 5867 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5868 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5869 } 5870 5871 private static boolean hasWebURI(Intent intent) { 5872 if (intent.getData() == null) { 5873 return false; 5874 } 5875 final String scheme = intent.getScheme(); 5876 if (TextUtils.isEmpty(scheme)) { 5877 return false; 5878 } 5879 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5880 } 5881 5882 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5883 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5884 int userId) { 5885 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5886 5887 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5888 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5889 candidates.size()); 5890 } 5891 5892 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5893 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5894 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5895 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5896 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5897 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5898 5899 synchronized (mPackages) { 5900 final int count = candidates.size(); 5901 // First, try to use linked apps. Partition the candidates into four lists: 5902 // one for the final results, one for the "do not use ever", one for "undefined status" 5903 // and finally one for "browser app type". 5904 for (int n=0; n<count; n++) { 5905 ResolveInfo info = candidates.get(n); 5906 String packageName = info.activityInfo.packageName; 5907 PackageSetting ps = mSettings.mPackages.get(packageName); 5908 if (ps != null) { 5909 // Add to the special match all list (Browser use case) 5910 if (info.handleAllWebDataURI) { 5911 matchAllList.add(info); 5912 continue; 5913 } 5914 // Try to get the status from User settings first 5915 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5916 int status = (int)(packedStatus >> 32); 5917 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5918 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5919 if (DEBUG_DOMAIN_VERIFICATION) { 5920 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5921 + " : linkgen=" + linkGeneration); 5922 } 5923 // Use link-enabled generation as preferredOrder, i.e. 5924 // prefer newly-enabled over earlier-enabled. 5925 info.preferredOrder = linkGeneration; 5926 alwaysList.add(info); 5927 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5928 if (DEBUG_DOMAIN_VERIFICATION) { 5929 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5930 } 5931 neverList.add(info); 5932 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5933 if (DEBUG_DOMAIN_VERIFICATION) { 5934 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5935 } 5936 alwaysAskList.add(info); 5937 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5938 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5939 if (DEBUG_DOMAIN_VERIFICATION) { 5940 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5941 } 5942 undefinedList.add(info); 5943 } 5944 } 5945 } 5946 5947 // We'll want to include browser possibilities in a few cases 5948 boolean includeBrowser = false; 5949 5950 // First try to add the "always" resolution(s) for the current user, if any 5951 if (alwaysList.size() > 0) { 5952 result.addAll(alwaysList); 5953 } else { 5954 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5955 result.addAll(undefinedList); 5956 // Maybe add one for the other profile. 5957 if (xpDomainInfo != null && ( 5958 xpDomainInfo.bestDomainVerificationStatus 5959 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5960 result.add(xpDomainInfo.resolveInfo); 5961 } 5962 includeBrowser = true; 5963 } 5964 5965 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5966 // If there were 'always' entries their preferred order has been set, so we also 5967 // back that off to make the alternatives equivalent 5968 if (alwaysAskList.size() > 0) { 5969 for (ResolveInfo i : result) { 5970 i.preferredOrder = 0; 5971 } 5972 result.addAll(alwaysAskList); 5973 includeBrowser = true; 5974 } 5975 5976 if (includeBrowser) { 5977 // Also add browsers (all of them or only the default one) 5978 if (DEBUG_DOMAIN_VERIFICATION) { 5979 Slog.v(TAG, " ...including browsers in candidate set"); 5980 } 5981 if ((matchFlags & MATCH_ALL) != 0) { 5982 result.addAll(matchAllList); 5983 } else { 5984 // Browser/generic handling case. If there's a default browser, go straight 5985 // to that (but only if there is no other higher-priority match). 5986 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5987 int maxMatchPrio = 0; 5988 ResolveInfo defaultBrowserMatch = null; 5989 final int numCandidates = matchAllList.size(); 5990 for (int n = 0; n < numCandidates; n++) { 5991 ResolveInfo info = matchAllList.get(n); 5992 // track the highest overall match priority... 5993 if (info.priority > maxMatchPrio) { 5994 maxMatchPrio = info.priority; 5995 } 5996 // ...and the highest-priority default browser match 5997 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5998 if (defaultBrowserMatch == null 5999 || (defaultBrowserMatch.priority < info.priority)) { 6000 if (debug) { 6001 Slog.v(TAG, "Considering default browser match " + info); 6002 } 6003 defaultBrowserMatch = info; 6004 } 6005 } 6006 } 6007 if (defaultBrowserMatch != null 6008 && defaultBrowserMatch.priority >= maxMatchPrio 6009 && !TextUtils.isEmpty(defaultBrowserPackageName)) 6010 { 6011 if (debug) { 6012 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 6013 } 6014 result.add(defaultBrowserMatch); 6015 } else { 6016 result.addAll(matchAllList); 6017 } 6018 } 6019 6020 // If there is nothing selected, add all candidates and remove the ones that the user 6021 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 6022 if (result.size() == 0) { 6023 result.addAll(candidates); 6024 result.removeAll(neverList); 6025 } 6026 } 6027 } 6028 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 6029 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 6030 result.size()); 6031 for (ResolveInfo info : result) { 6032 Slog.v(TAG, " + " + info.activityInfo); 6033 } 6034 } 6035 return result; 6036 } 6037 6038 // Returns a packed value as a long: 6039 // 6040 // high 'int'-sized word: link status: undefined/ask/never/always. 6041 // low 'int'-sized word: relative priority among 'always' results. 6042 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 6043 long result = ps.getDomainVerificationStatusForUser(userId); 6044 // if none available, get the master status 6045 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 6046 if (ps.getIntentFilterVerificationInfo() != null) { 6047 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 6048 } 6049 } 6050 return result; 6051 } 6052 6053 private ResolveInfo querySkipCurrentProfileIntents( 6054 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6055 int flags, int sourceUserId) { 6056 if (matchingFilters != null) { 6057 int size = matchingFilters.size(); 6058 for (int i = 0; i < size; i ++) { 6059 CrossProfileIntentFilter filter = matchingFilters.get(i); 6060 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 6061 // Checking if there are activities in the target user that can handle the 6062 // intent. 6063 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6064 resolvedType, flags, sourceUserId); 6065 if (resolveInfo != null) { 6066 return resolveInfo; 6067 } 6068 } 6069 } 6070 } 6071 return null; 6072 } 6073 6074 // Return matching ResolveInfo in target user if any. 6075 private ResolveInfo queryCrossProfileIntents( 6076 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 6077 int flags, int sourceUserId, boolean matchInCurrentProfile) { 6078 if (matchingFilters != null) { 6079 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 6080 // match the same intent. For performance reasons, it is better not to 6081 // run queryIntent twice for the same userId 6082 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 6083 int size = matchingFilters.size(); 6084 for (int i = 0; i < size; i++) { 6085 CrossProfileIntentFilter filter = matchingFilters.get(i); 6086 int targetUserId = filter.getTargetUserId(); 6087 boolean skipCurrentProfile = 6088 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 6089 boolean skipCurrentProfileIfNoMatchFound = 6090 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 6091 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 6092 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 6093 // Checking if there are activities in the target user that can handle the 6094 // intent. 6095 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 6096 resolvedType, flags, sourceUserId); 6097 if (resolveInfo != null) return resolveInfo; 6098 alreadyTriedUserIds.put(targetUserId, true); 6099 } 6100 } 6101 } 6102 return null; 6103 } 6104 6105 /** 6106 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 6107 * will forward the intent to the filter's target user. 6108 * Otherwise, returns null. 6109 */ 6110 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 6111 String resolvedType, int flags, int sourceUserId) { 6112 int targetUserId = filter.getTargetUserId(); 6113 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 6114 resolvedType, flags, targetUserId); 6115 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 6116 // If all the matches in the target profile are suspended, return null. 6117 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 6118 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 6119 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 6120 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 6121 targetUserId); 6122 } 6123 } 6124 } 6125 return null; 6126 } 6127 6128 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 6129 int sourceUserId, int targetUserId) { 6130 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 6131 long ident = Binder.clearCallingIdentity(); 6132 boolean targetIsProfile; 6133 try { 6134 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 6135 } finally { 6136 Binder.restoreCallingIdentity(ident); 6137 } 6138 String className; 6139 if (targetIsProfile) { 6140 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 6141 } else { 6142 className = FORWARD_INTENT_TO_PARENT; 6143 } 6144 ComponentName forwardingActivityComponentName = new ComponentName( 6145 mAndroidApplication.packageName, className); 6146 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 6147 sourceUserId); 6148 if (!targetIsProfile) { 6149 forwardingActivityInfo.showUserIcon = targetUserId; 6150 forwardingResolveInfo.noResourceId = true; 6151 } 6152 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 6153 forwardingResolveInfo.priority = 0; 6154 forwardingResolveInfo.preferredOrder = 0; 6155 forwardingResolveInfo.match = 0; 6156 forwardingResolveInfo.isDefault = true; 6157 forwardingResolveInfo.filter = filter; 6158 forwardingResolveInfo.targetUserId = targetUserId; 6159 return forwardingResolveInfo; 6160 } 6161 6162 @Override 6163 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 6164 Intent[] specifics, String[] specificTypes, Intent intent, 6165 String resolvedType, int flags, int userId) { 6166 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 6167 specificTypes, intent, resolvedType, flags, userId)); 6168 } 6169 6170 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 6171 Intent[] specifics, String[] specificTypes, Intent intent, 6172 String resolvedType, int flags, int userId) { 6173 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6174 flags = updateFlagsForResolve(flags, userId, intent); 6175 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6176 false /* requireFullPermission */, false /* checkShell */, 6177 "query intent activity options"); 6178 final String resultsAction = intent.getAction(); 6179 6180 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 6181 | PackageManager.GET_RESOLVED_FILTER, userId); 6182 6183 if (DEBUG_INTENT_MATCHING) { 6184 Log.v(TAG, "Query " + intent + ": " + results); 6185 } 6186 6187 int specificsPos = 0; 6188 int N; 6189 6190 // todo: note that the algorithm used here is O(N^2). This 6191 // isn't a problem in our current environment, but if we start running 6192 // into situations where we have more than 5 or 10 matches then this 6193 // should probably be changed to something smarter... 6194 6195 // First we go through and resolve each of the specific items 6196 // that were supplied, taking care of removing any corresponding 6197 // duplicate items in the generic resolve list. 6198 if (specifics != null) { 6199 for (int i=0; i<specifics.length; i++) { 6200 final Intent sintent = specifics[i]; 6201 if (sintent == null) { 6202 continue; 6203 } 6204 6205 if (DEBUG_INTENT_MATCHING) { 6206 Log.v(TAG, "Specific #" + i + ": " + sintent); 6207 } 6208 6209 String action = sintent.getAction(); 6210 if (resultsAction != null && resultsAction.equals(action)) { 6211 // If this action was explicitly requested, then don't 6212 // remove things that have it. 6213 action = null; 6214 } 6215 6216 ResolveInfo ri = null; 6217 ActivityInfo ai = null; 6218 6219 ComponentName comp = sintent.getComponent(); 6220 if (comp == null) { 6221 ri = resolveIntent( 6222 sintent, 6223 specificTypes != null ? specificTypes[i] : null, 6224 flags, userId); 6225 if (ri == null) { 6226 continue; 6227 } 6228 if (ri == mResolveInfo) { 6229 // ACK! Must do something better with this. 6230 } 6231 ai = ri.activityInfo; 6232 comp = new ComponentName(ai.applicationInfo.packageName, 6233 ai.name); 6234 } else { 6235 ai = getActivityInfo(comp, flags, userId); 6236 if (ai == null) { 6237 continue; 6238 } 6239 } 6240 6241 // Look for any generic query activities that are duplicates 6242 // of this specific one, and remove them from the results. 6243 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 6244 N = results.size(); 6245 int j; 6246 for (j=specificsPos; j<N; j++) { 6247 ResolveInfo sri = results.get(j); 6248 if ((sri.activityInfo.name.equals(comp.getClassName()) 6249 && sri.activityInfo.applicationInfo.packageName.equals( 6250 comp.getPackageName())) 6251 || (action != null && sri.filter.matchAction(action))) { 6252 results.remove(j); 6253 if (DEBUG_INTENT_MATCHING) Log.v( 6254 TAG, "Removing duplicate item from " + j 6255 + " due to specific " + specificsPos); 6256 if (ri == null) { 6257 ri = sri; 6258 } 6259 j--; 6260 N--; 6261 } 6262 } 6263 6264 // Add this specific item to its proper place. 6265 if (ri == null) { 6266 ri = new ResolveInfo(); 6267 ri.activityInfo = ai; 6268 } 6269 results.add(specificsPos, ri); 6270 ri.specificIndex = i; 6271 specificsPos++; 6272 } 6273 } 6274 6275 // Now we go through the remaining generic results and remove any 6276 // duplicate actions that are found here. 6277 N = results.size(); 6278 for (int i=specificsPos; i<N-1; i++) { 6279 final ResolveInfo rii = results.get(i); 6280 if (rii.filter == null) { 6281 continue; 6282 } 6283 6284 // Iterate over all of the actions of this result's intent 6285 // filter... typically this should be just one. 6286 final Iterator<String> it = rii.filter.actionsIterator(); 6287 if (it == null) { 6288 continue; 6289 } 6290 while (it.hasNext()) { 6291 final String action = it.next(); 6292 if (resultsAction != null && resultsAction.equals(action)) { 6293 // If this action was explicitly requested, then don't 6294 // remove things that have it. 6295 continue; 6296 } 6297 for (int j=i+1; j<N; j++) { 6298 final ResolveInfo rij = results.get(j); 6299 if (rij.filter != null && rij.filter.hasAction(action)) { 6300 results.remove(j); 6301 if (DEBUG_INTENT_MATCHING) Log.v( 6302 TAG, "Removing duplicate item from " + j 6303 + " due to action " + action + " at " + i); 6304 j--; 6305 N--; 6306 } 6307 } 6308 } 6309 6310 // If the caller didn't request filter information, drop it now 6311 // so we don't have to marshall/unmarshall it. 6312 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6313 rii.filter = null; 6314 } 6315 } 6316 6317 // Filter out the caller activity if so requested. 6318 if (caller != null) { 6319 N = results.size(); 6320 for (int i=0; i<N; i++) { 6321 ActivityInfo ainfo = results.get(i).activityInfo; 6322 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 6323 && caller.getClassName().equals(ainfo.name)) { 6324 results.remove(i); 6325 break; 6326 } 6327 } 6328 } 6329 6330 // If the caller didn't request filter information, 6331 // drop them now so we don't have to 6332 // marshall/unmarshall it. 6333 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6334 N = results.size(); 6335 for (int i=0; i<N; i++) { 6336 results.get(i).filter = null; 6337 } 6338 } 6339 6340 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 6341 return results; 6342 } 6343 6344 @Override 6345 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 6346 String resolvedType, int flags, int userId) { 6347 return new ParceledListSlice<>( 6348 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 6349 } 6350 6351 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 6352 String resolvedType, int flags, int userId) { 6353 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6354 flags = updateFlagsForResolve(flags, userId, intent); 6355 ComponentName comp = intent.getComponent(); 6356 if (comp == null) { 6357 if (intent.getSelector() != null) { 6358 intent = intent.getSelector(); 6359 comp = intent.getComponent(); 6360 } 6361 } 6362 if (comp != null) { 6363 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6364 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 6365 if (ai != null) { 6366 ResolveInfo ri = new ResolveInfo(); 6367 ri.activityInfo = ai; 6368 list.add(ri); 6369 } 6370 return list; 6371 } 6372 6373 // reader 6374 synchronized (mPackages) { 6375 String pkgName = intent.getPackage(); 6376 if (pkgName == null) { 6377 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 6378 } 6379 final PackageParser.Package pkg = mPackages.get(pkgName); 6380 if (pkg != null) { 6381 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 6382 userId); 6383 } 6384 return Collections.emptyList(); 6385 } 6386 } 6387 6388 @Override 6389 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 6390 if (!sUserManager.exists(userId)) return null; 6391 flags = updateFlagsForResolve(flags, userId, intent); 6392 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 6393 if (query != null) { 6394 if (query.size() >= 1) { 6395 // If there is more than one service with the same priority, 6396 // just arbitrarily pick the first one. 6397 return query.get(0); 6398 } 6399 } 6400 return null; 6401 } 6402 6403 @Override 6404 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 6405 String resolvedType, int flags, int userId) { 6406 return new ParceledListSlice<>( 6407 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 6408 } 6409 6410 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 6411 String resolvedType, int flags, int userId) { 6412 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6413 flags = updateFlagsForResolve(flags, userId, intent); 6414 ComponentName comp = intent.getComponent(); 6415 if (comp == null) { 6416 if (intent.getSelector() != null) { 6417 intent = intent.getSelector(); 6418 comp = intent.getComponent(); 6419 } 6420 } 6421 if (comp != null) { 6422 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6423 final ServiceInfo si = getServiceInfo(comp, flags, userId); 6424 if (si != null) { 6425 final ResolveInfo ri = new ResolveInfo(); 6426 ri.serviceInfo = si; 6427 list.add(ri); 6428 } 6429 return list; 6430 } 6431 6432 // reader 6433 synchronized (mPackages) { 6434 String pkgName = intent.getPackage(); 6435 if (pkgName == null) { 6436 return mServices.queryIntent(intent, resolvedType, flags, userId); 6437 } 6438 final PackageParser.Package pkg = mPackages.get(pkgName); 6439 if (pkg != null) { 6440 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 6441 userId); 6442 } 6443 return Collections.emptyList(); 6444 } 6445 } 6446 6447 @Override 6448 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 6449 String resolvedType, int flags, int userId) { 6450 return new ParceledListSlice<>( 6451 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 6452 } 6453 6454 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 6455 Intent intent, String resolvedType, int flags, int userId) { 6456 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6457 flags = updateFlagsForResolve(flags, userId, intent); 6458 ComponentName comp = intent.getComponent(); 6459 if (comp == null) { 6460 if (intent.getSelector() != null) { 6461 intent = intent.getSelector(); 6462 comp = intent.getComponent(); 6463 } 6464 } 6465 if (comp != null) { 6466 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6467 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 6468 if (pi != null) { 6469 final ResolveInfo ri = new ResolveInfo(); 6470 ri.providerInfo = pi; 6471 list.add(ri); 6472 } 6473 return list; 6474 } 6475 6476 // reader 6477 synchronized (mPackages) { 6478 String pkgName = intent.getPackage(); 6479 if (pkgName == null) { 6480 return mProviders.queryIntent(intent, resolvedType, flags, userId); 6481 } 6482 final PackageParser.Package pkg = mPackages.get(pkgName); 6483 if (pkg != null) { 6484 return mProviders.queryIntentForPackage( 6485 intent, resolvedType, flags, pkg.providers, userId); 6486 } 6487 return Collections.emptyList(); 6488 } 6489 } 6490 6491 @Override 6492 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 6493 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6494 flags = updateFlagsForPackage(flags, userId, null); 6495 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 6496 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6497 true /* requireFullPermission */, false /* checkShell */, 6498 "get installed packages"); 6499 6500 // writer 6501 synchronized (mPackages) { 6502 ArrayList<PackageInfo> list; 6503 if (listUninstalled) { 6504 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 6505 for (PackageSetting ps : mSettings.mPackages.values()) { 6506 final PackageInfo pi; 6507 if (ps.pkg != null) { 6508 pi = generatePackageInfo(ps, flags, userId); 6509 } else { 6510 pi = generatePackageInfo(ps, flags, userId); 6511 } 6512 if (pi != null) { 6513 list.add(pi); 6514 } 6515 } 6516 } else { 6517 list = new ArrayList<PackageInfo>(mPackages.size()); 6518 for (PackageParser.Package p : mPackages.values()) { 6519 final PackageInfo pi = 6520 generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 6521 if (pi != null) { 6522 list.add(pi); 6523 } 6524 } 6525 } 6526 6527 return new ParceledListSlice<PackageInfo>(list); 6528 } 6529 } 6530 6531 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 6532 String[] permissions, boolean[] tmp, int flags, int userId) { 6533 int numMatch = 0; 6534 final PermissionsState permissionsState = ps.getPermissionsState(); 6535 for (int i=0; i<permissions.length; i++) { 6536 final String permission = permissions[i]; 6537 if (permissionsState.hasPermission(permission, userId)) { 6538 tmp[i] = true; 6539 numMatch++; 6540 } else { 6541 tmp[i] = false; 6542 } 6543 } 6544 if (numMatch == 0) { 6545 return; 6546 } 6547 final PackageInfo pi; 6548 if (ps.pkg != null) { 6549 pi = generatePackageInfo(ps, flags, userId); 6550 } else { 6551 pi = generatePackageInfo(ps, flags, userId); 6552 } 6553 // The above might return null in cases of uninstalled apps or install-state 6554 // skew across users/profiles. 6555 if (pi != null) { 6556 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 6557 if (numMatch == permissions.length) { 6558 pi.requestedPermissions = permissions; 6559 } else { 6560 pi.requestedPermissions = new String[numMatch]; 6561 numMatch = 0; 6562 for (int i=0; i<permissions.length; i++) { 6563 if (tmp[i]) { 6564 pi.requestedPermissions[numMatch] = permissions[i]; 6565 numMatch++; 6566 } 6567 } 6568 } 6569 } 6570 list.add(pi); 6571 } 6572 } 6573 6574 @Override 6575 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 6576 String[] permissions, int flags, int userId) { 6577 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6578 flags = updateFlagsForPackage(flags, userId, permissions); 6579 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6580 true /* requireFullPermission */, false /* checkShell */, 6581 "get packages holding permissions"); 6582 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 6583 6584 // writer 6585 synchronized (mPackages) { 6586 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 6587 boolean[] tmpBools = new boolean[permissions.length]; 6588 if (listUninstalled) { 6589 for (PackageSetting ps : mSettings.mPackages.values()) { 6590 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6591 userId); 6592 } 6593 } else { 6594 for (PackageParser.Package pkg : mPackages.values()) { 6595 PackageSetting ps = (PackageSetting)pkg.mExtras; 6596 if (ps != null) { 6597 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6598 userId); 6599 } 6600 } 6601 } 6602 6603 return new ParceledListSlice<PackageInfo>(list); 6604 } 6605 } 6606 6607 @Override 6608 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6609 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6610 flags = updateFlagsForApplication(flags, userId, null); 6611 final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; 6612 6613 // writer 6614 synchronized (mPackages) { 6615 ArrayList<ApplicationInfo> list; 6616 if (listUninstalled) { 6617 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6618 for (PackageSetting ps : mSettings.mPackages.values()) { 6619 ApplicationInfo ai; 6620 int effectiveFlags = flags; 6621 if (ps.isSystem()) { 6622 effectiveFlags |= PackageManager.MATCH_ANY_USER; 6623 } 6624 if (ps.pkg != null) { 6625 ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags, 6626 ps.readUserState(userId), userId); 6627 } else { 6628 ai = generateApplicationInfoFromSettingsLPw(ps.name, effectiveFlags, 6629 userId); 6630 } 6631 if (ai != null) { 6632 list.add(ai); 6633 } 6634 } 6635 } else { 6636 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6637 for (PackageParser.Package p : mPackages.values()) { 6638 if (p.mExtras != null) { 6639 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6640 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6641 if (ai != null) { 6642 list.add(ai); 6643 } 6644 } 6645 } 6646 } 6647 6648 return new ParceledListSlice<ApplicationInfo>(list); 6649 } 6650 } 6651 6652 @Override 6653 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6654 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6655 return null; 6656 } 6657 6658 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6659 "getEphemeralApplications"); 6660 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6661 true /* requireFullPermission */, false /* checkShell */, 6662 "getEphemeralApplications"); 6663 synchronized (mPackages) { 6664 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6665 .getEphemeralApplicationsLPw(userId); 6666 if (ephemeralApps != null) { 6667 return new ParceledListSlice<>(ephemeralApps); 6668 } 6669 } 6670 return null; 6671 } 6672 6673 @Override 6674 public boolean isEphemeralApplication(String packageName, int userId) { 6675 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6676 true /* requireFullPermission */, false /* checkShell */, 6677 "isEphemeral"); 6678 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6679 return false; 6680 } 6681 6682 if (!isCallerSameApp(packageName)) { 6683 return false; 6684 } 6685 synchronized (mPackages) { 6686 PackageParser.Package pkg = mPackages.get(packageName); 6687 if (pkg != null) { 6688 return pkg.applicationInfo.isEphemeralApp(); 6689 } 6690 } 6691 return false; 6692 } 6693 6694 @Override 6695 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6696 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6697 return null; 6698 } 6699 6700 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6701 true /* requireFullPermission */, false /* checkShell */, 6702 "getCookie"); 6703 if (!isCallerSameApp(packageName)) { 6704 return null; 6705 } 6706 synchronized (mPackages) { 6707 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6708 packageName, userId); 6709 } 6710 } 6711 6712 @Override 6713 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6714 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6715 return true; 6716 } 6717 6718 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6719 true /* requireFullPermission */, true /* checkShell */, 6720 "setCookie"); 6721 if (!isCallerSameApp(packageName)) { 6722 return false; 6723 } 6724 synchronized (mPackages) { 6725 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6726 packageName, cookie, userId); 6727 } 6728 } 6729 6730 @Override 6731 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6732 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6733 return null; 6734 } 6735 6736 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6737 "getEphemeralApplicationIcon"); 6738 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6739 true /* requireFullPermission */, false /* checkShell */, 6740 "getEphemeralApplicationIcon"); 6741 synchronized (mPackages) { 6742 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6743 packageName, userId); 6744 } 6745 } 6746 6747 private boolean isCallerSameApp(String packageName) { 6748 PackageParser.Package pkg = mPackages.get(packageName); 6749 return pkg != null 6750 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6751 } 6752 6753 @Override 6754 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6755 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6756 } 6757 6758 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6759 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6760 6761 // reader 6762 synchronized (mPackages) { 6763 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6764 final int userId = UserHandle.getCallingUserId(); 6765 while (i.hasNext()) { 6766 final PackageParser.Package p = i.next(); 6767 if (p.applicationInfo == null) continue; 6768 6769 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6770 && !p.applicationInfo.isDirectBootAware(); 6771 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6772 && p.applicationInfo.isDirectBootAware(); 6773 6774 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6775 && (!mSafeMode || isSystemApp(p)) 6776 && (matchesUnaware || matchesAware)) { 6777 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6778 if (ps != null) { 6779 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6780 ps.readUserState(userId), userId); 6781 if (ai != null) { 6782 finalList.add(ai); 6783 } 6784 } 6785 } 6786 } 6787 } 6788 6789 return finalList; 6790 } 6791 6792 @Override 6793 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6794 if (!sUserManager.exists(userId)) return null; 6795 flags = updateFlagsForComponent(flags, userId, name); 6796 // reader 6797 synchronized (mPackages) { 6798 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6799 PackageSetting ps = provider != null 6800 ? mSettings.mPackages.get(provider.owner.packageName) 6801 : null; 6802 return ps != null 6803 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6804 ? PackageParser.generateProviderInfo(provider, flags, 6805 ps.readUserState(userId), userId) 6806 : null; 6807 } 6808 } 6809 6810 /** 6811 * @deprecated 6812 */ 6813 @Deprecated 6814 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6815 // reader 6816 synchronized (mPackages) { 6817 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6818 .entrySet().iterator(); 6819 final int userId = UserHandle.getCallingUserId(); 6820 while (i.hasNext()) { 6821 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6822 PackageParser.Provider p = entry.getValue(); 6823 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6824 6825 if (ps != null && p.syncable 6826 && (!mSafeMode || (p.info.applicationInfo.flags 6827 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6828 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6829 ps.readUserState(userId), userId); 6830 if (info != null) { 6831 outNames.add(entry.getKey()); 6832 outInfo.add(info); 6833 } 6834 } 6835 } 6836 } 6837 } 6838 6839 @Override 6840 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6841 int uid, int flags) { 6842 final int userId = processName != null ? UserHandle.getUserId(uid) 6843 : UserHandle.getCallingUserId(); 6844 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6845 flags = updateFlagsForComponent(flags, userId, processName); 6846 6847 ArrayList<ProviderInfo> finalList = null; 6848 // reader 6849 synchronized (mPackages) { 6850 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6851 while (i.hasNext()) { 6852 final PackageParser.Provider p = i.next(); 6853 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6854 if (ps != null && p.info.authority != null 6855 && (processName == null 6856 || (p.info.processName.equals(processName) 6857 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6858 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6859 if (finalList == null) { 6860 finalList = new ArrayList<ProviderInfo>(3); 6861 } 6862 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6863 ps.readUserState(userId), userId); 6864 if (info != null) { 6865 finalList.add(info); 6866 } 6867 } 6868 } 6869 } 6870 6871 if (finalList != null) { 6872 Collections.sort(finalList, mProviderInitOrderSorter); 6873 return new ParceledListSlice<ProviderInfo>(finalList); 6874 } 6875 6876 return ParceledListSlice.emptyList(); 6877 } 6878 6879 @Override 6880 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6881 // reader 6882 synchronized (mPackages) { 6883 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6884 return PackageParser.generateInstrumentationInfo(i, flags); 6885 } 6886 } 6887 6888 @Override 6889 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6890 String targetPackage, int flags) { 6891 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6892 } 6893 6894 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6895 int flags) { 6896 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6897 6898 // reader 6899 synchronized (mPackages) { 6900 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6901 while (i.hasNext()) { 6902 final PackageParser.Instrumentation p = i.next(); 6903 if (targetPackage == null 6904 || targetPackage.equals(p.info.targetPackage)) { 6905 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6906 flags); 6907 if (ii != null) { 6908 finalList.add(ii); 6909 } 6910 } 6911 } 6912 } 6913 6914 return finalList; 6915 } 6916 6917 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6918 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6919 if (overlays == null) { 6920 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6921 return; 6922 } 6923 for (PackageParser.Package opkg : overlays.values()) { 6924 // Not much to do if idmap fails: we already logged the error 6925 // and we certainly don't want to abort installation of pkg simply 6926 // because an overlay didn't fit properly. For these reasons, 6927 // ignore the return value of createIdmapForPackagePairLI. 6928 createIdmapForPackagePairLI(pkg, opkg); 6929 } 6930 } 6931 6932 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6933 PackageParser.Package opkg) { 6934 if (!opkg.mTrustedOverlay) { 6935 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6936 opkg.baseCodePath + ": overlay not trusted"); 6937 return false; 6938 } 6939 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6940 if (overlaySet == null) { 6941 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6942 opkg.baseCodePath + " but target package has no known overlays"); 6943 return false; 6944 } 6945 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6946 // TODO: generate idmap for split APKs 6947 try { 6948 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6949 } catch (InstallerException e) { 6950 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6951 + opkg.baseCodePath); 6952 return false; 6953 } 6954 PackageParser.Package[] overlayArray = 6955 overlaySet.values().toArray(new PackageParser.Package[0]); 6956 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6957 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6958 return p1.mOverlayPriority - p2.mOverlayPriority; 6959 } 6960 }; 6961 Arrays.sort(overlayArray, cmp); 6962 6963 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6964 int i = 0; 6965 for (PackageParser.Package p : overlayArray) { 6966 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6967 } 6968 return true; 6969 } 6970 6971 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6972 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]"); 6973 try { 6974 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6975 } finally { 6976 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6977 } 6978 } 6979 6980 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6981 final File[] files = dir.listFiles(); 6982 if (ArrayUtils.isEmpty(files)) { 6983 Log.d(TAG, "No files in app dir " + dir); 6984 return; 6985 } 6986 6987 if (DEBUG_PACKAGE_SCANNING) { 6988 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6989 + " flags=0x" + Integer.toHexString(parseFlags)); 6990 } 6991 ParallelPackageParser parallelPackageParser = new ParallelPackageParser( 6992 mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir); 6993 6994 // Submit files for parsing in parallel 6995 int fileCount = 0; 6996 for (File file : files) { 6997 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6998 && !PackageInstallerService.isStageName(file.getName()); 6999 if (!isPackage) { 7000 // Ignore entries which are not packages 7001 continue; 7002 } 7003 parallelPackageParser.submit(file, parseFlags); 7004 fileCount++; 7005 } 7006 7007 // Process results one by one 7008 for (; fileCount > 0; fileCount--) { 7009 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); 7010 Throwable throwable = parseResult.throwable; 7011 int errorCode = PackageManager.INSTALL_SUCCEEDED; 7012 7013 if (throwable == null) { 7014 try { 7015 scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags, 7016 currentTime, null); 7017 } catch (PackageManagerException e) { 7018 errorCode = e.error; 7019 Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage()); 7020 } 7021 } else if (throwable instanceof PackageParser.PackageParserException) { 7022 PackageParser.PackageParserException e = (PackageParser.PackageParserException) 7023 throwable; 7024 errorCode = e.error; 7025 Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage()); 7026 } else { 7027 throw new IllegalStateException("Unexpected exception occurred while parsing " 7028 + parseResult.scanFile, throwable); 7029 } 7030 7031 // Delete invalid userdata apps 7032 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 7033 errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) { 7034 logCriticalInfo(Log.WARN, 7035 "Deleting invalid package at " + parseResult.scanFile); 7036 removeCodePathLI(parseResult.scanFile); 7037 } 7038 } 7039 parallelPackageParser.close(); 7040 } 7041 7042 private static File getSettingsProblemFile() { 7043 File dataDir = Environment.getDataDirectory(); 7044 File systemDir = new File(dataDir, "system"); 7045 File fname = new File(systemDir, "uiderrors.txt"); 7046 return fname; 7047 } 7048 7049 static void reportSettingsProblem(int priority, String msg) { 7050 logCriticalInfo(priority, msg); 7051 } 7052 7053 static void logCriticalInfo(int priority, String msg) { 7054 Slog.println(priority, TAG, msg); 7055 EventLogTags.writePmCriticalInfo(msg); 7056 try { 7057 File fname = getSettingsProblemFile(); 7058 FileOutputStream out = new FileOutputStream(fname, true); 7059 PrintWriter pw = new FastPrintWriter(out); 7060 SimpleDateFormat formatter = new SimpleDateFormat(); 7061 String dateString = formatter.format(new Date(System.currentTimeMillis())); 7062 pw.println(dateString + ": " + msg); 7063 pw.close(); 7064 FileUtils.setPermissions( 7065 fname.toString(), 7066 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 7067 -1, -1); 7068 } catch (java.io.IOException e) { 7069 } 7070 } 7071 7072 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 7073 if (srcFile.isDirectory()) { 7074 final File baseFile = new File(pkg.baseCodePath); 7075 long maxModifiedTime = baseFile.lastModified(); 7076 if (pkg.splitCodePaths != null) { 7077 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 7078 final File splitFile = new File(pkg.splitCodePaths[i]); 7079 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 7080 } 7081 } 7082 return maxModifiedTime; 7083 } 7084 return srcFile.lastModified(); 7085 } 7086 7087 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 7088 final int policyFlags) throws PackageManagerException { 7089 // When upgrading from pre-N MR1, verify the package time stamp using the package 7090 // directory and not the APK file. 7091 final long lastModifiedTime = mIsPreNMR1Upgrade 7092 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile); 7093 if (ps != null 7094 && ps.codePath.equals(srcFile) 7095 && ps.timeStamp == lastModifiedTime 7096 && !isCompatSignatureUpdateNeeded(pkg) 7097 && !isRecoverSignatureUpdateNeeded(pkg)) { 7098 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 7099 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7100 ArraySet<PublicKey> signingKs; 7101 synchronized (mPackages) { 7102 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 7103 } 7104 if (ps.signatures.mSignatures != null 7105 && ps.signatures.mSignatures.length != 0 7106 && signingKs != null) { 7107 // Optimization: reuse the existing cached certificates 7108 // if the package appears to be unchanged. 7109 pkg.mSignatures = ps.signatures.mSignatures; 7110 pkg.mSigningKeys = signingKs; 7111 return; 7112 } 7113 7114 Slog.w(TAG, "PackageSetting for " + ps.name 7115 + " is missing signatures. Collecting certs again to recover them."); 7116 } else { 7117 Slog.i(TAG, srcFile.toString() + " changed; collecting certs"); 7118 } 7119 7120 try { 7121 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 7122 PackageParser.collectCertificates(pkg, policyFlags); 7123 } catch (PackageParserException e) { 7124 throw PackageManagerException.from(e); 7125 } finally { 7126 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7127 } 7128 } 7129 7130 /** 7131 * Traces a package scan. 7132 * @see #scanPackageLI(File, int, int, long, UserHandle) 7133 */ 7134 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 7135 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7136 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 7137 try { 7138 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 7139 } finally { 7140 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7141 } 7142 } 7143 7144 /** 7145 * Scans a package and returns the newly parsed package. 7146 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 7147 */ 7148 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 7149 long currentTime, UserHandle user) throws PackageManagerException { 7150 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 7151 PackageParser pp = new PackageParser(); 7152 pp.setSeparateProcesses(mSeparateProcesses); 7153 pp.setOnlyCoreApps(mOnlyCore); 7154 pp.setDisplayMetrics(mMetrics); 7155 7156 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 7157 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 7158 } 7159 7160 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 7161 final PackageParser.Package pkg; 7162 try { 7163 pkg = pp.parsePackage(scanFile, parseFlags); 7164 } catch (PackageParserException e) { 7165 throw PackageManagerException.from(e); 7166 } finally { 7167 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7168 } 7169 7170 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 7171 } 7172 7173 /** 7174 * Scans a package and returns the newly parsed package. 7175 * @throws PackageManagerException on a parse error. 7176 */ 7177 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 7178 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 7179 throws PackageManagerException { 7180 // If the package has children and this is the first dive in the function 7181 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 7182 // packages (parent and children) would be successfully scanned before the 7183 // actual scan since scanning mutates internal state and we want to atomically 7184 // install the package and its children. 7185 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7186 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7187 scanFlags |= SCAN_CHECK_ONLY; 7188 } 7189 } else { 7190 scanFlags &= ~SCAN_CHECK_ONLY; 7191 } 7192 7193 // Scan the parent 7194 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 7195 scanFlags, currentTime, user); 7196 7197 // Scan the children 7198 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7199 for (int i = 0; i < childCount; i++) { 7200 PackageParser.Package childPackage = pkg.childPackages.get(i); 7201 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 7202 currentTime, user); 7203 } 7204 7205 7206 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7207 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 7208 } 7209 7210 return scannedPkg; 7211 } 7212 7213 /** 7214 * Scans a package and returns the newly parsed package. 7215 * @throws PackageManagerException on a parse error. 7216 */ 7217 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 7218 int policyFlags, int scanFlags, long currentTime, UserHandle user) 7219 throws PackageManagerException { 7220 PackageSetting ps = null; 7221 PackageSetting updatedPkg; 7222 // reader 7223 synchronized (mPackages) { 7224 // Look to see if we already know about this package. 7225 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName); 7226 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 7227 // This package has been renamed to its original name. Let's 7228 // use that. 7229 ps = mSettings.getPackageLPr(oldName); 7230 } 7231 // If there was no original package, see one for the real package name. 7232 if (ps == null) { 7233 ps = mSettings.getPackageLPr(pkg.packageName); 7234 } 7235 // Check to see if this package could be hiding/updating a system 7236 // package. Must look for it either under the original or real 7237 // package name depending on our state. 7238 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 7239 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 7240 7241 // If this is a package we don't know about on the system partition, we 7242 // may need to remove disabled child packages on the system partition 7243 // or may need to not add child packages if the parent apk is updated 7244 // on the data partition and no longer defines this child package. 7245 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7246 // If this is a parent package for an updated system app and this system 7247 // app got an OTA update which no longer defines some of the child packages 7248 // we have to prune them from the disabled system packages. 7249 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 7250 if (disabledPs != null) { 7251 final int scannedChildCount = (pkg.childPackages != null) 7252 ? pkg.childPackages.size() : 0; 7253 final int disabledChildCount = disabledPs.childPackageNames != null 7254 ? disabledPs.childPackageNames.size() : 0; 7255 for (int i = 0; i < disabledChildCount; i++) { 7256 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 7257 boolean disabledPackageAvailable = false; 7258 for (int j = 0; j < scannedChildCount; j++) { 7259 PackageParser.Package childPkg = pkg.childPackages.get(j); 7260 if (childPkg.packageName.equals(disabledChildPackageName)) { 7261 disabledPackageAvailable = true; 7262 break; 7263 } 7264 } 7265 if (!disabledPackageAvailable) { 7266 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 7267 } 7268 } 7269 } 7270 } 7271 } 7272 7273 boolean updatedPkgBetter = false; 7274 // First check if this is a system package that may involve an update 7275 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 7276 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 7277 // it needs to drop FLAG_PRIVILEGED. 7278 if (locationIsPrivileged(scanFile)) { 7279 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7280 } else { 7281 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7282 } 7283 7284 if (ps != null && !ps.codePath.equals(scanFile)) { 7285 // The path has changed from what was last scanned... check the 7286 // version of the new path against what we have stored to determine 7287 // what to do. 7288 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 7289 if (pkg.mVersionCode <= ps.versionCode) { 7290 // The system package has been updated and the code path does not match 7291 // Ignore entry. Skip it. 7292 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 7293 + " ignored: updated version " + ps.versionCode 7294 + " better than this " + pkg.mVersionCode); 7295 if (!updatedPkg.codePath.equals(scanFile)) { 7296 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 7297 + ps.name + " changing from " + updatedPkg.codePathString 7298 + " to " + scanFile); 7299 updatedPkg.codePath = scanFile; 7300 updatedPkg.codePathString = scanFile.toString(); 7301 updatedPkg.resourcePath = scanFile; 7302 updatedPkg.resourcePathString = scanFile.toString(); 7303 } 7304 updatedPkg.pkg = pkg; 7305 updatedPkg.versionCode = pkg.mVersionCode; 7306 7307 // Update the disabled system child packages to point to the package too. 7308 final int childCount = updatedPkg.childPackageNames != null 7309 ? updatedPkg.childPackageNames.size() : 0; 7310 for (int i = 0; i < childCount; i++) { 7311 String childPackageName = updatedPkg.childPackageNames.get(i); 7312 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 7313 childPackageName); 7314 if (updatedChildPkg != null) { 7315 updatedChildPkg.pkg = pkg; 7316 updatedChildPkg.versionCode = pkg.mVersionCode; 7317 } 7318 } 7319 7320 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 7321 + scanFile + " ignored: updated version " + ps.versionCode 7322 + " better than this " + pkg.mVersionCode); 7323 } else { 7324 // The current app on the system partition is better than 7325 // what we have updated to on the data partition; switch 7326 // back to the system partition version. 7327 // At this point, its safely assumed that package installation for 7328 // apps in system partition will go through. If not there won't be a working 7329 // version of the app 7330 // writer 7331 synchronized (mPackages) { 7332 // Just remove the loaded entries from package lists. 7333 mPackages.remove(ps.name); 7334 } 7335 7336 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7337 + " reverting from " + ps.codePathString 7338 + ": new version " + pkg.mVersionCode 7339 + " better than installed " + ps.versionCode); 7340 7341 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7342 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7343 synchronized (mInstallLock) { 7344 args.cleanUpResourcesLI(); 7345 } 7346 synchronized (mPackages) { 7347 mSettings.enableSystemPackageLPw(ps.name); 7348 } 7349 updatedPkgBetter = true; 7350 } 7351 } 7352 } 7353 7354 if (updatedPkg != null) { 7355 // An updated system app will not have the PARSE_IS_SYSTEM flag set 7356 // initially 7357 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 7358 7359 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 7360 // flag set initially 7361 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 7362 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 7363 } 7364 } 7365 7366 // Verify certificates against what was last scanned 7367 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 7368 7369 /* 7370 * A new system app appeared, but we already had a non-system one of the 7371 * same name installed earlier. 7372 */ 7373 boolean shouldHideSystemApp = false; 7374 if (updatedPkg == null && ps != null 7375 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 7376 /* 7377 * Check to make sure the signatures match first. If they don't, 7378 * wipe the installed application and its data. 7379 */ 7380 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 7381 != PackageManager.SIGNATURE_MATCH) { 7382 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 7383 + " signatures don't match existing userdata copy; removing"); 7384 try (PackageFreezer freezer = freezePackage(pkg.packageName, 7385 "scanPackageInternalLI")) { 7386 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 7387 } 7388 ps = null; 7389 } else { 7390 /* 7391 * If the newly-added system app is an older version than the 7392 * already installed version, hide it. It will be scanned later 7393 * and re-added like an update. 7394 */ 7395 if (pkg.mVersionCode <= ps.versionCode) { 7396 shouldHideSystemApp = true; 7397 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 7398 + " but new version " + pkg.mVersionCode + " better than installed " 7399 + ps.versionCode + "; hiding system"); 7400 } else { 7401 /* 7402 * The newly found system app is a newer version that the 7403 * one previously installed. Simply remove the 7404 * already-installed application and replace it with our own 7405 * while keeping the application data. 7406 */ 7407 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7408 + " reverting from " + ps.codePathString + ": new version " 7409 + pkg.mVersionCode + " better than installed " + ps.versionCode); 7410 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7411 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7412 synchronized (mInstallLock) { 7413 args.cleanUpResourcesLI(); 7414 } 7415 } 7416 } 7417 } 7418 7419 // The apk is forward locked (not public) if its code and resources 7420 // are kept in different files. (except for app in either system or 7421 // vendor path). 7422 // TODO grab this value from PackageSettings 7423 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7424 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 7425 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 7426 } 7427 } 7428 7429 // TODO: extend to support forward-locked splits 7430 String resourcePath = null; 7431 String baseResourcePath = null; 7432 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 7433 if (ps != null && ps.resourcePathString != null) { 7434 resourcePath = ps.resourcePathString; 7435 baseResourcePath = ps.resourcePathString; 7436 } else { 7437 // Should not happen at all. Just log an error. 7438 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 7439 } 7440 } else { 7441 resourcePath = pkg.codePath; 7442 baseResourcePath = pkg.baseCodePath; 7443 } 7444 7445 // Set application objects path explicitly. 7446 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 7447 pkg.setApplicationInfoCodePath(pkg.codePath); 7448 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 7449 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 7450 pkg.setApplicationInfoResourcePath(resourcePath); 7451 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 7452 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 7453 7454 // Note that we invoke the following method only if we are about to unpack an application 7455 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 7456 | SCAN_UPDATE_SIGNATURE, currentTime, user); 7457 7458 /* 7459 * If the system app should be overridden by a previously installed 7460 * data, hide the system app now and let the /data/app scan pick it up 7461 * again. 7462 */ 7463 if (shouldHideSystemApp) { 7464 synchronized (mPackages) { 7465 mSettings.disableSystemPackageLPw(pkg.packageName, true); 7466 } 7467 } 7468 7469 return scannedPkg; 7470 } 7471 7472 private static String fixProcessName(String defProcessName, 7473 String processName) { 7474 if (processName == null) { 7475 return defProcessName; 7476 } 7477 return processName; 7478 } 7479 7480 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 7481 throws PackageManagerException { 7482 if (pkgSetting.signatures.mSignatures != null) { 7483 // Already existing package. Make sure signatures match 7484 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 7485 == PackageManager.SIGNATURE_MATCH; 7486 if (!match) { 7487 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 7488 == PackageManager.SIGNATURE_MATCH; 7489 } 7490 if (!match) { 7491 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 7492 == PackageManager.SIGNATURE_MATCH; 7493 } 7494 if (!match) { 7495 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 7496 + pkg.packageName + " signatures do not match the " 7497 + "previously installed version; ignoring!"); 7498 } 7499 } 7500 7501 // Check for shared user signatures 7502 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 7503 // Already existing package. Make sure signatures match 7504 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7505 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 7506 if (!match) { 7507 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 7508 == PackageManager.SIGNATURE_MATCH; 7509 } 7510 if (!match) { 7511 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 7512 == PackageManager.SIGNATURE_MATCH; 7513 } 7514 if (!match) { 7515 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 7516 "Package " + pkg.packageName 7517 + " has no signatures that match those in shared user " 7518 + pkgSetting.sharedUser.name + "; ignoring!"); 7519 } 7520 } 7521 } 7522 7523 /** 7524 * Enforces that only the system UID or root's UID can call a method exposed 7525 * via Binder. 7526 * 7527 * @param message used as message if SecurityException is thrown 7528 * @throws SecurityException if the caller is not system or root 7529 */ 7530 private static final void enforceSystemOrRoot(String message) { 7531 final int uid = Binder.getCallingUid(); 7532 if (uid != Process.SYSTEM_UID && uid != 0) { 7533 throw new SecurityException(message); 7534 } 7535 } 7536 7537 @Override 7538 public void performFstrimIfNeeded() { 7539 enforceSystemOrRoot("Only the system can request fstrim"); 7540 7541 // Before everything else, see whether we need to fstrim. 7542 try { 7543 IStorageManager sm = PackageHelper.getStorageManager(); 7544 if (sm != null) { 7545 boolean doTrim = false; 7546 final long interval = android.provider.Settings.Global.getLong( 7547 mContext.getContentResolver(), 7548 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 7549 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 7550 if (interval > 0) { 7551 final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance(); 7552 if (timeSinceLast > interval) { 7553 doTrim = true; 7554 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 7555 + "; running immediately"); 7556 } 7557 } 7558 if (doTrim) { 7559 final boolean dexOptDialogShown; 7560 synchronized (mPackages) { 7561 dexOptDialogShown = mDexOptDialogShown; 7562 } 7563 if (!isFirstBoot() && dexOptDialogShown) { 7564 try { 7565 ActivityManager.getService().showBootMessage( 7566 mContext.getResources().getString( 7567 R.string.android_upgrading_fstrim), true); 7568 } catch (RemoteException e) { 7569 } 7570 } 7571 sm.runMaintenance(); 7572 } 7573 } else { 7574 Slog.e(TAG, "storageManager service unavailable!"); 7575 } 7576 } catch (RemoteException e) { 7577 // Can't happen; StorageManagerService is local 7578 } 7579 } 7580 7581 @Override 7582 public void updatePackagesIfNeeded() { 7583 enforceSystemOrRoot("Only the system can request package update"); 7584 7585 // We need to re-extract after an OTA. 7586 boolean causeUpgrade = isUpgrade(); 7587 7588 // First boot or factory reset. 7589 // Note: we also handle devices that are upgrading to N right now as if it is their 7590 // first boot, as they do not have profile data. 7591 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 7592 7593 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 7594 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 7595 7596 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 7597 return; 7598 } 7599 7600 List<PackageParser.Package> pkgs; 7601 synchronized (mPackages) { 7602 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 7603 } 7604 7605 final long startTime = System.nanoTime(); 7606 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 7607 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 7608 7609 final int elapsedTimeSeconds = 7610 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 7611 7612 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 7613 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 7614 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 7615 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 7616 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 7617 } 7618 7619 /** 7620 * Performs dexopt on the set of packages in {@code packages} and returns an int array 7621 * containing statistics about the invocation. The array consists of three elements, 7622 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 7623 * and {@code numberOfPackagesFailed}. 7624 */ 7625 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 7626 String compilerFilter) { 7627 7628 int numberOfPackagesVisited = 0; 7629 int numberOfPackagesOptimized = 0; 7630 int numberOfPackagesSkipped = 0; 7631 int numberOfPackagesFailed = 0; 7632 final int numberOfPackagesToDexopt = pkgs.size(); 7633 7634 for (PackageParser.Package pkg : pkgs) { 7635 numberOfPackagesVisited++; 7636 7637 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 7638 if (DEBUG_DEXOPT) { 7639 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 7640 } 7641 numberOfPackagesSkipped++; 7642 continue; 7643 } 7644 7645 if (DEBUG_DEXOPT) { 7646 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 7647 numberOfPackagesToDexopt + ": " + pkg.packageName); 7648 } 7649 7650 if (showDialog) { 7651 try { 7652 ActivityManager.getService().showBootMessage( 7653 mContext.getResources().getString(R.string.android_upgrading_apk, 7654 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 7655 } catch (RemoteException e) { 7656 } 7657 synchronized (mPackages) { 7658 mDexOptDialogShown = true; 7659 } 7660 } 7661 7662 // If the OTA updates a system app which was previously preopted to a non-preopted state 7663 // the app might end up being verified at runtime. That's because by default the apps 7664 // are verify-profile but for preopted apps there's no profile. 7665 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 7666 // that before the OTA the app was preopted) the app gets compiled with a non-profile 7667 // filter (by default interpret-only). 7668 // Note that at this stage unused apps are already filtered. 7669 if (isSystemApp(pkg) && 7670 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 7671 !Environment.getReferenceProfile(pkg.packageName).exists()) { 7672 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 7673 } 7674 7675 // checkProfiles is false to avoid merging profiles during boot which 7676 // might interfere with background compilation (b/28612421). 7677 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 7678 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 7679 // trade-off worth doing to save boot time work. 7680 int dexOptStatus = performDexOptTraced(pkg.packageName, 7681 false /* checkProfiles */, 7682 compilerFilter, 7683 false /* force */); 7684 switch (dexOptStatus) { 7685 case PackageDexOptimizer.DEX_OPT_PERFORMED: 7686 numberOfPackagesOptimized++; 7687 break; 7688 case PackageDexOptimizer.DEX_OPT_SKIPPED: 7689 numberOfPackagesSkipped++; 7690 break; 7691 case PackageDexOptimizer.DEX_OPT_FAILED: 7692 numberOfPackagesFailed++; 7693 break; 7694 default: 7695 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 7696 break; 7697 } 7698 } 7699 7700 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 7701 numberOfPackagesFailed }; 7702 } 7703 7704 @Override 7705 public void notifyPackageUse(String packageName, int reason) { 7706 synchronized (mPackages) { 7707 PackageParser.Package p = mPackages.get(packageName); 7708 if (p == null) { 7709 return; 7710 } 7711 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 7712 } 7713 } 7714 7715 @Override 7716 public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) { 7717 int userId = UserHandle.getCallingUserId(); 7718 ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId); 7719 if (ai == null) { 7720 Slog.w(TAG, "Loading a package that does not exist for the calling user. package=" 7721 + loadingPackageName + ", user=" + userId); 7722 return; 7723 } 7724 mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId); 7725 } 7726 7727 // TODO: this is not used nor needed. Delete it. 7728 @Override 7729 public boolean performDexOptIfNeeded(String packageName) { 7730 int dexOptStatus = performDexOptTraced(packageName, 7731 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 7732 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7733 } 7734 7735 @Override 7736 public boolean performDexOpt(String packageName, 7737 boolean checkProfiles, int compileReason, boolean force) { 7738 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7739 getCompilerFilterForReason(compileReason), force); 7740 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7741 } 7742 7743 @Override 7744 public boolean performDexOptMode(String packageName, 7745 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7746 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7747 targetCompilerFilter, force); 7748 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7749 } 7750 7751 private int performDexOptTraced(String packageName, 7752 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7753 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7754 try { 7755 return performDexOptInternal(packageName, checkProfiles, 7756 targetCompilerFilter, force); 7757 } finally { 7758 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7759 } 7760 } 7761 7762 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 7763 // if the package can now be considered up to date for the given filter. 7764 private int performDexOptInternal(String packageName, 7765 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7766 PackageParser.Package p; 7767 synchronized (mPackages) { 7768 p = mPackages.get(packageName); 7769 if (p == null) { 7770 // Package could not be found. Report failure. 7771 return PackageDexOptimizer.DEX_OPT_FAILED; 7772 } 7773 mPackageUsage.maybeWriteAsync(mPackages); 7774 mCompilerStats.maybeWriteAsync(); 7775 } 7776 long callingId = Binder.clearCallingIdentity(); 7777 try { 7778 synchronized (mInstallLock) { 7779 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 7780 targetCompilerFilter, force); 7781 } 7782 } finally { 7783 Binder.restoreCallingIdentity(callingId); 7784 } 7785 } 7786 7787 public ArraySet<String> getOptimizablePackages() { 7788 ArraySet<String> pkgs = new ArraySet<String>(); 7789 synchronized (mPackages) { 7790 for (PackageParser.Package p : mPackages.values()) { 7791 if (PackageDexOptimizer.canOptimizePackage(p)) { 7792 pkgs.add(p.packageName); 7793 } 7794 } 7795 } 7796 return pkgs; 7797 } 7798 7799 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7800 boolean checkProfiles, String targetCompilerFilter, 7801 boolean force) { 7802 // Select the dex optimizer based on the force parameter. 7803 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7804 // allocate an object here. 7805 PackageDexOptimizer pdo = force 7806 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7807 : mPackageDexOptimizer; 7808 7809 // Optimize all dependencies first. Note: we ignore the return value and march on 7810 // on errors. 7811 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7812 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 7813 if (!deps.isEmpty()) { 7814 for (PackageParser.Package depPackage : deps) { 7815 // TODO: Analyze and investigate if we (should) profile libraries. 7816 // Currently this will do a full compilation of the library by default. 7817 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 7818 false /* checkProfiles */, 7819 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 7820 getOrCreateCompilerPackageStats(depPackage)); 7821 } 7822 } 7823 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 7824 targetCompilerFilter, getOrCreateCompilerPackageStats(p)); 7825 } 7826 7827 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7828 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7829 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7830 Set<String> collectedNames = new HashSet<>(); 7831 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7832 7833 retValue.remove(p); 7834 7835 return retValue; 7836 } else { 7837 return Collections.emptyList(); 7838 } 7839 } 7840 7841 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7842 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7843 if (!collectedNames.contains(p.packageName)) { 7844 collectedNames.add(p.packageName); 7845 collected.add(p); 7846 7847 if (p.usesLibraries != null) { 7848 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7849 } 7850 if (p.usesOptionalLibraries != null) { 7851 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7852 collectedNames); 7853 } 7854 } 7855 } 7856 7857 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7858 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7859 for (String libName : libs) { 7860 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7861 if (libPkg != null) { 7862 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7863 } 7864 } 7865 } 7866 7867 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7868 synchronized (mPackages) { 7869 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7870 if (lib != null && lib.apk != null) { 7871 return mPackages.get(lib.apk); 7872 } 7873 } 7874 return null; 7875 } 7876 7877 public void shutdown() { 7878 mPackageUsage.writeNow(mPackages); 7879 mCompilerStats.writeNow(); 7880 } 7881 7882 @Override 7883 public void dumpProfiles(String packageName) { 7884 PackageParser.Package pkg; 7885 synchronized (mPackages) { 7886 pkg = mPackages.get(packageName); 7887 if (pkg == null) { 7888 throw new IllegalArgumentException("Unknown package: " + packageName); 7889 } 7890 } 7891 /* Only the shell, root, or the app user should be able to dump profiles. */ 7892 int callingUid = Binder.getCallingUid(); 7893 if (callingUid != Process.SHELL_UID && 7894 callingUid != Process.ROOT_UID && 7895 callingUid != pkg.applicationInfo.uid) { 7896 throw new SecurityException("dumpProfiles"); 7897 } 7898 7899 synchronized (mInstallLock) { 7900 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 7901 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 7902 try { 7903 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 7904 String codePaths = TextUtils.join(";", allCodePaths); 7905 mInstaller.dumpProfiles(sharedGid, packageName, codePaths); 7906 } catch (InstallerException e) { 7907 Slog.w(TAG, "Failed to dump profiles", e); 7908 } 7909 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7910 } 7911 } 7912 7913 @Override 7914 public void forceDexOpt(String packageName) { 7915 enforceSystemOrRoot("forceDexOpt"); 7916 7917 PackageParser.Package pkg; 7918 synchronized (mPackages) { 7919 pkg = mPackages.get(packageName); 7920 if (pkg == null) { 7921 throw new IllegalArgumentException("Unknown package: " + packageName); 7922 } 7923 } 7924 7925 synchronized (mInstallLock) { 7926 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7927 7928 // Whoever is calling forceDexOpt wants a fully compiled package. 7929 // Don't use profiles since that may cause compilation to be skipped. 7930 final int res = performDexOptInternalWithDependenciesLI(pkg, 7931 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7932 true /* force */); 7933 7934 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7935 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7936 throw new IllegalStateException("Failed to dexopt: " + res); 7937 } 7938 } 7939 } 7940 7941 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7942 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7943 Slog.w(TAG, "Unable to update from " + oldPkg.name 7944 + " to " + newPkg.packageName 7945 + ": old package not in system partition"); 7946 return false; 7947 } else if (mPackages.get(oldPkg.name) != null) { 7948 Slog.w(TAG, "Unable to update from " + oldPkg.name 7949 + " to " + newPkg.packageName 7950 + ": old package still exists"); 7951 return false; 7952 } 7953 return true; 7954 } 7955 7956 void removeCodePathLI(File codePath) { 7957 if (codePath.isDirectory()) { 7958 try { 7959 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7960 } catch (InstallerException e) { 7961 Slog.w(TAG, "Failed to remove code path", e); 7962 } 7963 } else { 7964 codePath.delete(); 7965 } 7966 } 7967 7968 private int[] resolveUserIds(int userId) { 7969 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 7970 } 7971 7972 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7973 if (pkg == null) { 7974 Slog.wtf(TAG, "Package was null!", new Throwable()); 7975 return; 7976 } 7977 clearAppDataLeafLIF(pkg, userId, flags); 7978 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7979 for (int i = 0; i < childCount; i++) { 7980 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7981 } 7982 } 7983 7984 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7985 final PackageSetting ps; 7986 synchronized (mPackages) { 7987 ps = mSettings.mPackages.get(pkg.packageName); 7988 } 7989 for (int realUserId : resolveUserIds(userId)) { 7990 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7991 try { 7992 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7993 ceDataInode); 7994 } catch (InstallerException e) { 7995 Slog.w(TAG, String.valueOf(e)); 7996 } 7997 } 7998 } 7999 8000 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 8001 if (pkg == null) { 8002 Slog.wtf(TAG, "Package was null!", new Throwable()); 8003 return; 8004 } 8005 destroyAppDataLeafLIF(pkg, userId, flags); 8006 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8007 for (int i = 0; i < childCount; i++) { 8008 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 8009 } 8010 } 8011 8012 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 8013 final PackageSetting ps; 8014 synchronized (mPackages) { 8015 ps = mSettings.mPackages.get(pkg.packageName); 8016 } 8017 for (int realUserId : resolveUserIds(userId)) { 8018 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 8019 try { 8020 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 8021 ceDataInode); 8022 } catch (InstallerException e) { 8023 Slog.w(TAG, String.valueOf(e)); 8024 } 8025 } 8026 } 8027 8028 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 8029 if (pkg == null) { 8030 Slog.wtf(TAG, "Package was null!", new Throwable()); 8031 return; 8032 } 8033 destroyAppProfilesLeafLIF(pkg); 8034 destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */); 8035 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8036 for (int i = 0; i < childCount; i++) { 8037 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 8038 destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId, 8039 true /* removeBaseMarker */); 8040 } 8041 } 8042 8043 private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, 8044 boolean removeBaseMarker) { 8045 if (pkg.isForwardLocked()) { 8046 return; 8047 } 8048 8049 for (String path : pkg.getAllCodePathsExcludingResourceOnly()) { 8050 try { 8051 path = PackageManagerServiceUtils.realpath(new File(path)); 8052 } catch (IOException e) { 8053 // TODO: Should we return early here ? 8054 Slog.w(TAG, "Failed to get canonical path", e); 8055 continue; 8056 } 8057 8058 final String useMarker = path.replace('/', '@'); 8059 for (int realUserId : resolveUserIds(userId)) { 8060 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId); 8061 if (removeBaseMarker) { 8062 File foreignUseMark = new File(profileDir, useMarker); 8063 if (foreignUseMark.exists()) { 8064 if (!foreignUseMark.delete()) { 8065 Slog.w(TAG, "Unable to delete foreign user mark for package: " 8066 + pkg.packageName); 8067 } 8068 } 8069 } 8070 8071 File[] markers = profileDir.listFiles(); 8072 if (markers != null) { 8073 final String searchString = "@" + pkg.packageName + "@"; 8074 // We also delete all markers that contain the package name we're 8075 // uninstalling. These are associated with secondary dex-files belonging 8076 // to the package. Reconstructing the path of these dex files is messy 8077 // in general. 8078 for (File marker : markers) { 8079 if (marker.getName().indexOf(searchString) > 0) { 8080 if (!marker.delete()) { 8081 Slog.w(TAG, "Unable to delete foreign user mark for package: " 8082 + pkg.packageName); 8083 } 8084 } 8085 } 8086 } 8087 } 8088 } 8089 } 8090 8091 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 8092 try { 8093 mInstaller.destroyAppProfiles(pkg.packageName); 8094 } catch (InstallerException e) { 8095 Slog.w(TAG, String.valueOf(e)); 8096 } 8097 } 8098 8099 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 8100 if (pkg == null) { 8101 Slog.wtf(TAG, "Package was null!", new Throwable()); 8102 return; 8103 } 8104 clearAppProfilesLeafLIF(pkg); 8105 // We don't remove the base foreign use marker when clearing profiles because 8106 // we will rename it when the app is updated. Unlike the actual profile contents, 8107 // the foreign use marker is good across installs. 8108 destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */); 8109 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8110 for (int i = 0; i < childCount; i++) { 8111 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 8112 } 8113 } 8114 8115 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 8116 try { 8117 mInstaller.clearAppProfiles(pkg.packageName); 8118 } catch (InstallerException e) { 8119 Slog.w(TAG, String.valueOf(e)); 8120 } 8121 } 8122 8123 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 8124 long lastUpdateTime) { 8125 // Set parent install/update time 8126 PackageSetting ps = (PackageSetting) pkg.mExtras; 8127 if (ps != null) { 8128 ps.firstInstallTime = firstInstallTime; 8129 ps.lastUpdateTime = lastUpdateTime; 8130 } 8131 // Set children install/update time 8132 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8133 for (int i = 0; i < childCount; i++) { 8134 PackageParser.Package childPkg = pkg.childPackages.get(i); 8135 ps = (PackageSetting) childPkg.mExtras; 8136 if (ps != null) { 8137 ps.firstInstallTime = firstInstallTime; 8138 ps.lastUpdateTime = lastUpdateTime; 8139 } 8140 } 8141 } 8142 8143 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 8144 PackageParser.Package changingLib) { 8145 if (file.path != null) { 8146 usesLibraryFiles.add(file.path); 8147 return; 8148 } 8149 PackageParser.Package p = mPackages.get(file.apk); 8150 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 8151 // If we are doing this while in the middle of updating a library apk, 8152 // then we need to make sure to use that new apk for determining the 8153 // dependencies here. (We haven't yet finished committing the new apk 8154 // to the package manager state.) 8155 if (p == null || p.packageName.equals(changingLib.packageName)) { 8156 p = changingLib; 8157 } 8158 } 8159 if (p != null) { 8160 usesLibraryFiles.addAll(p.getAllCodePaths()); 8161 } 8162 } 8163 8164 private void updateSharedLibrariesLPr(PackageParser.Package pkg, 8165 PackageParser.Package changingLib) throws PackageManagerException { 8166 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 8167 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 8168 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 8169 for (int i=0; i<N; i++) { 8170 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 8171 if (file == null) { 8172 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 8173 "Package " + pkg.packageName + " requires unavailable shared library " 8174 + pkg.usesLibraries.get(i) + "; failing!"); 8175 } 8176 addSharedLibraryLPr(usesLibraryFiles, file, changingLib); 8177 } 8178 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 8179 for (int i=0; i<N; i++) { 8180 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 8181 if (file == null) { 8182 Slog.w(TAG, "Package " + pkg.packageName 8183 + " desires unavailable shared library " 8184 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 8185 } else { 8186 addSharedLibraryLPr(usesLibraryFiles, file, changingLib); 8187 } 8188 } 8189 N = usesLibraryFiles.size(); 8190 if (N > 0) { 8191 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 8192 } else { 8193 pkg.usesLibraryFiles = null; 8194 } 8195 } 8196 } 8197 8198 private static boolean hasString(List<String> list, List<String> which) { 8199 if (list == null) { 8200 return false; 8201 } 8202 for (int i=list.size()-1; i>=0; i--) { 8203 for (int j=which.size()-1; j>=0; j--) { 8204 if (which.get(j).equals(list.get(i))) { 8205 return true; 8206 } 8207 } 8208 } 8209 return false; 8210 } 8211 8212 private void updateAllSharedLibrariesLPw() { 8213 for (PackageParser.Package pkg : mPackages.values()) { 8214 try { 8215 updateSharedLibrariesLPr(pkg, null); 8216 } catch (PackageManagerException e) { 8217 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 8218 } 8219 } 8220 } 8221 8222 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 8223 PackageParser.Package changingPkg) { 8224 ArrayList<PackageParser.Package> res = null; 8225 for (PackageParser.Package pkg : mPackages.values()) { 8226 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 8227 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 8228 if (res == null) { 8229 res = new ArrayList<PackageParser.Package>(); 8230 } 8231 res.add(pkg); 8232 try { 8233 updateSharedLibrariesLPr(pkg, changingPkg); 8234 } catch (PackageManagerException e) { 8235 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 8236 } 8237 } 8238 } 8239 return res; 8240 } 8241 8242 /** 8243 * Derive the value of the {@code cpuAbiOverride} based on the provided 8244 * value and an optional stored value from the package settings. 8245 */ 8246 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 8247 String cpuAbiOverride = null; 8248 8249 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 8250 cpuAbiOverride = null; 8251 } else if (abiOverride != null) { 8252 cpuAbiOverride = abiOverride; 8253 } else if (settings != null) { 8254 cpuAbiOverride = settings.cpuAbiOverrideString; 8255 } 8256 8257 return cpuAbiOverride; 8258 } 8259 8260 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 8261 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 8262 throws PackageManagerException { 8263 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 8264 // If the package has children and this is the first dive in the function 8265 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 8266 // whether all packages (parent and children) would be successfully scanned 8267 // before the actual scan since scanning mutates internal state and we want 8268 // to atomically install the package and its children. 8269 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8270 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 8271 scanFlags |= SCAN_CHECK_ONLY; 8272 } 8273 } else { 8274 scanFlags &= ~SCAN_CHECK_ONLY; 8275 } 8276 8277 final PackageParser.Package scannedPkg; 8278 try { 8279 // Scan the parent 8280 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 8281 // Scan the children 8282 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8283 for (int i = 0; i < childCount; i++) { 8284 PackageParser.Package childPkg = pkg.childPackages.get(i); 8285 scanPackageLI(childPkg, policyFlags, 8286 scanFlags, currentTime, user); 8287 } 8288 } finally { 8289 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8290 } 8291 8292 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8293 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 8294 } 8295 8296 return scannedPkg; 8297 } 8298 8299 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 8300 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 8301 boolean success = false; 8302 try { 8303 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 8304 currentTime, user); 8305 success = true; 8306 return res; 8307 } finally { 8308 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 8309 // DELETE_DATA_ON_FAILURES is only used by frozen paths 8310 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 8311 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 8312 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 8313 } 8314 } 8315 } 8316 8317 /** 8318 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 8319 */ 8320 private static boolean apkHasCode(String fileName) { 8321 StrictJarFile jarFile = null; 8322 try { 8323 jarFile = new StrictJarFile(fileName, 8324 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 8325 return jarFile.findEntry("classes.dex") != null; 8326 } catch (IOException ignore) { 8327 } finally { 8328 try { 8329 if (jarFile != null) { 8330 jarFile.close(); 8331 } 8332 } catch (IOException ignore) {} 8333 } 8334 return false; 8335 } 8336 8337 /** 8338 * Enforces code policy for the package. This ensures that if an APK has 8339 * declared hasCode="true" in its manifest that the APK actually contains 8340 * code. 8341 * 8342 * @throws PackageManagerException If bytecode could not be found when it should exist 8343 */ 8344 private static void assertCodePolicy(PackageParser.Package pkg) 8345 throws PackageManagerException { 8346 final boolean shouldHaveCode = 8347 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 8348 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 8349 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8350 "Package " + pkg.baseCodePath + " code is missing"); 8351 } 8352 8353 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 8354 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 8355 final boolean splitShouldHaveCode = 8356 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 8357 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 8358 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8359 "Package " + pkg.splitCodePaths[i] + " code is missing"); 8360 } 8361 } 8362 } 8363 } 8364 8365 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 8366 final int policyFlags, final int scanFlags, long currentTime, UserHandle user) 8367 throws PackageManagerException { 8368 if (DEBUG_PACKAGE_SCANNING) { 8369 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8370 Log.d(TAG, "Scanning package " + pkg.packageName); 8371 } 8372 8373 applyPolicy(pkg, policyFlags); 8374 8375 assertPackageIsValid(pkg, policyFlags, scanFlags); 8376 8377 // Initialize package source and resource directories 8378 final File scanFile = new File(pkg.codePath); 8379 final File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 8380 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 8381 8382 SharedUserSetting suid = null; 8383 PackageSetting pkgSetting = null; 8384 8385 // Getting the package setting may have a side-effect, so if we 8386 // are only checking if scan would succeed, stash a copy of the 8387 // old setting to restore at the end. 8388 PackageSetting nonMutatedPs = null; 8389 8390 // We keep references to the derived CPU Abis from settings in oder to reuse 8391 // them in the case where we're not upgrading or booting for the first time. 8392 String primaryCpuAbiFromSettings = null; 8393 String secondaryCpuAbiFromSettings = null; 8394 8395 // writer 8396 synchronized (mPackages) { 8397 if (pkg.mSharedUserId != null) { 8398 // SIDE EFFECTS; may potentially allocate a new shared user 8399 suid = mSettings.getSharedUserLPw( 8400 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); 8401 if (DEBUG_PACKAGE_SCANNING) { 8402 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8403 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 8404 + "): packages=" + suid.packages); 8405 } 8406 } 8407 8408 // Check if we are renaming from an original package name. 8409 PackageSetting origPackage = null; 8410 String realName = null; 8411 if (pkg.mOriginalPackages != null) { 8412 // This package may need to be renamed to a previously 8413 // installed name. Let's check on that... 8414 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage); 8415 if (pkg.mOriginalPackages.contains(renamed)) { 8416 // This package had originally been installed as the 8417 // original name, and we have already taken care of 8418 // transitioning to the new one. Just update the new 8419 // one to continue using the old name. 8420 realName = pkg.mRealPackage; 8421 if (!pkg.packageName.equals(renamed)) { 8422 // Callers into this function may have already taken 8423 // care of renaming the package; only do it here if 8424 // it is not already done. 8425 pkg.setPackageName(renamed); 8426 } 8427 } else { 8428 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 8429 if ((origPackage = mSettings.getPackageLPr( 8430 pkg.mOriginalPackages.get(i))) != null) { 8431 // We do have the package already installed under its 8432 // original name... should we use it? 8433 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 8434 // New package is not compatible with original. 8435 origPackage = null; 8436 continue; 8437 } else if (origPackage.sharedUser != null) { 8438 // Make sure uid is compatible between packages. 8439 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 8440 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 8441 + " to " + pkg.packageName + ": old uid " 8442 + origPackage.sharedUser.name 8443 + " differs from " + pkg.mSharedUserId); 8444 origPackage = null; 8445 continue; 8446 } 8447 // TODO: Add case when shared user id is added [b/28144775] 8448 } else { 8449 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 8450 + pkg.packageName + " to old name " + origPackage.name); 8451 } 8452 break; 8453 } 8454 } 8455 } 8456 } 8457 8458 if (mTransferedPackages.contains(pkg.packageName)) { 8459 Slog.w(TAG, "Package " + pkg.packageName 8460 + " was transferred to another, but its .apk remains"); 8461 } 8462 8463 // See comments in nonMutatedPs declaration 8464 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8465 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 8466 if (foundPs != null) { 8467 nonMutatedPs = new PackageSetting(foundPs); 8468 } 8469 } 8470 8471 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) { 8472 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 8473 if (foundPs != null) { 8474 primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString; 8475 secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString; 8476 } 8477 } 8478 8479 pkgSetting = mSettings.getPackageLPr(pkg.packageName); 8480 if (pkgSetting != null && pkgSetting.sharedUser != suid) { 8481 PackageManagerService.reportSettingsProblem(Log.WARN, 8482 "Package " + pkg.packageName + " shared user changed from " 8483 + (pkgSetting.sharedUser != null 8484 ? pkgSetting.sharedUser.name : "<nothing>") 8485 + " to " 8486 + (suid != null ? suid.name : "<nothing>") 8487 + "; replacing with new"); 8488 pkgSetting = null; 8489 } 8490 final PackageSetting oldPkgSetting = 8491 pkgSetting == null ? null : new PackageSetting(pkgSetting); 8492 final PackageSetting disabledPkgSetting = 8493 mSettings.getDisabledSystemPkgLPr(pkg.packageName); 8494 if (pkgSetting == null) { 8495 final String parentPackageName = (pkg.parentPackage != null) 8496 ? pkg.parentPackage.packageName : null; 8497 // REMOVE SharedUserSetting from method; update in a separate call 8498 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage, 8499 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile, 8500 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi, 8501 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode, 8502 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user, 8503 true /*allowInstall*/, parentPackageName, pkg.getChildPackageNames(), 8504 UserManagerService.getInstance()); 8505 // SIDE EFFECTS; updates system state; move elsewhere 8506 if (origPackage != null) { 8507 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name); 8508 } 8509 mSettings.addUserToSettingLPw(pkgSetting); 8510 } else { 8511 // REMOVE SharedUserSetting from method; update in a separate call. 8512 // 8513 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi, 8514 // secondaryCpuAbi are not known at this point so we always update them 8515 // to null here, only to reset them at a later point. 8516 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile, 8517 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi, 8518 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags, 8519 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(), 8520 UserManagerService.getInstance()); 8521 } 8522 // SIDE EFFECTS; persists system state to files on disk; move elsewhere 8523 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); 8524 8525 // SIDE EFFECTS; modifies system state; move elsewhere 8526 if (pkgSetting.origPackage != null) { 8527 // If we are first transitioning from an original package, 8528 // fix up the new package's name now. We need to do this after 8529 // looking up the package under its new name, so getPackageLP 8530 // can take care of fiddling things correctly. 8531 pkg.setPackageName(origPackage.name); 8532 8533 // File a report about this. 8534 String msg = "New package " + pkgSetting.realName 8535 + " renamed to replace old package " + pkgSetting.name; 8536 reportSettingsProblem(Log.WARN, msg); 8537 8538 // Make a note of it. 8539 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8540 mTransferedPackages.add(origPackage.name); 8541 } 8542 8543 // No longer need to retain this. 8544 pkgSetting.origPackage = null; 8545 } 8546 8547 // SIDE EFFECTS; modifies system state; move elsewhere 8548 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 8549 // Make a note of it. 8550 mTransferedPackages.add(pkg.packageName); 8551 } 8552 8553 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 8554 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 8555 } 8556 8557 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8558 // Check all shared libraries and map to their actual file path. 8559 // We only do this here for apps not on a system dir, because those 8560 // are the only ones that can fail an install due to this. We 8561 // will take care of the system apps by updating all of their 8562 // library paths after the scan is done. 8563 updateSharedLibrariesLPr(pkg, null); 8564 } 8565 8566 if (mFoundPolicyFile) { 8567 SELinuxMMAC.assignSeinfoValue(pkg); 8568 } 8569 8570 pkg.applicationInfo.uid = pkgSetting.appId; 8571 pkg.mExtras = pkgSetting; 8572 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 8573 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 8574 // We just determined the app is signed correctly, so bring 8575 // over the latest parsed certs. 8576 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8577 } else { 8578 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8579 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8580 "Package " + pkg.packageName + " upgrade keys do not match the " 8581 + "previously installed version"); 8582 } else { 8583 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8584 String msg = "System package " + pkg.packageName 8585 + " signature changed; retaining data."; 8586 reportSettingsProblem(Log.WARN, msg); 8587 } 8588 } 8589 } else { 8590 try { 8591 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService 8592 verifySignaturesLP(pkgSetting, pkg); 8593 // We just determined the app is signed correctly, so bring 8594 // over the latest parsed certs. 8595 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8596 } catch (PackageManagerException e) { 8597 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8598 throw e; 8599 } 8600 // The signature has changed, but this package is in the system 8601 // image... let's recover! 8602 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8603 // However... if this package is part of a shared user, but it 8604 // doesn't match the signature of the shared user, let's fail. 8605 // What this means is that you can't change the signatures 8606 // associated with an overall shared user, which doesn't seem all 8607 // that unreasonable. 8608 if (pkgSetting.sharedUser != null) { 8609 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8610 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 8611 throw new PackageManagerException( 8612 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 8613 "Signature mismatch for shared user: " 8614 + pkgSetting.sharedUser); 8615 } 8616 } 8617 // File a report about this. 8618 String msg = "System package " + pkg.packageName 8619 + " signature changed; retaining data."; 8620 reportSettingsProblem(Log.WARN, msg); 8621 } 8622 } 8623 8624 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 8625 // This package wants to adopt ownership of permissions from 8626 // another package. 8627 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 8628 final String origName = pkg.mAdoptPermissions.get(i); 8629 final PackageSetting orig = mSettings.getPackageLPr(origName); 8630 if (orig != null) { 8631 if (verifyPackageUpdateLPr(orig, pkg)) { 8632 Slog.i(TAG, "Adopting permissions from " + origName + " to " 8633 + pkg.packageName); 8634 // SIDE EFFECTS; updates permissions system state; move elsewhere 8635 mSettings.transferPermissionsLPw(origName, pkg.packageName); 8636 } 8637 } 8638 } 8639 } 8640 } 8641 8642 pkg.applicationInfo.processName = fixProcessName( 8643 pkg.applicationInfo.packageName, 8644 pkg.applicationInfo.processName); 8645 8646 if (pkg != mPlatformPackage) { 8647 // Get all of our default paths setup 8648 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 8649 } 8650 8651 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 8652 8653 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 8654 if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) { 8655 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); 8656 derivePackageAbi( 8657 pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir); 8658 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8659 8660 // Some system apps still use directory structure for native libraries 8661 // in which case we might end up not detecting abi solely based on apk 8662 // structure. Try to detect abi based on directory structure. 8663 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 8664 pkg.applicationInfo.primaryCpuAbi == null) { 8665 setBundledAppAbisAndRoots(pkg, pkgSetting); 8666 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 8667 } 8668 } else { 8669 // This is not a first boot or an upgrade, don't bother deriving the 8670 // ABI during the scan. Instead, trust the value that was stored in the 8671 // package setting. 8672 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; 8673 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings; 8674 8675 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 8676 8677 if (DEBUG_ABI_SELECTION) { 8678 Slog.i(TAG, "Using ABIS and native lib paths from settings : " + 8679 pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " + 8680 pkg.applicationInfo.secondaryCpuAbi); 8681 } 8682 } 8683 } else { 8684 if ((scanFlags & SCAN_MOVE) != 0) { 8685 // We haven't run dex-opt for this move (since we've moved the compiled output too) 8686 // but we already have this packages package info in the PackageSetting. We just 8687 // use that and derive the native library path based on the new codepath. 8688 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 8689 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 8690 } 8691 8692 // Set native library paths again. For moves, the path will be updated based on the 8693 // ABIs we've determined above. For non-moves, the path will be updated based on the 8694 // ABIs we determined during compilation, but the path will depend on the final 8695 // package path (after the rename away from the stage path). 8696 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 8697 } 8698 8699 // This is a special case for the "system" package, where the ABI is 8700 // dictated by the zygote configuration (and init.rc). We should keep track 8701 // of this ABI so that we can deal with "normal" applications that run under 8702 // the same UID correctly. 8703 if (mPlatformPackage == pkg) { 8704 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 8705 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 8706 } 8707 8708 // If there's a mismatch between the abi-override in the package setting 8709 // and the abiOverride specified for the install. Warn about this because we 8710 // would've already compiled the app without taking the package setting into 8711 // account. 8712 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 8713 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 8714 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 8715 " for package " + pkg.packageName); 8716 } 8717 } 8718 8719 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8720 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8721 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 8722 8723 // Copy the derived override back to the parsed package, so that we can 8724 // update the package settings accordingly. 8725 pkg.cpuAbiOverride = cpuAbiOverride; 8726 8727 if (DEBUG_ABI_SELECTION) { 8728 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 8729 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 8730 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 8731 } 8732 8733 // Push the derived path down into PackageSettings so we know what to 8734 // clean up at uninstall time. 8735 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 8736 8737 if (DEBUG_ABI_SELECTION) { 8738 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 8739 " primary=" + pkg.applicationInfo.primaryCpuAbi + 8740 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 8741 } 8742 8743 // SIDE EFFECTS; removes DEX files from disk; move elsewhere 8744 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 8745 // We don't do this here during boot because we can do it all 8746 // at once after scanning all existing packages. 8747 // 8748 // We also do this *before* we perform dexopt on this package, so that 8749 // we can avoid redundant dexopts, and also to make sure we've got the 8750 // code and package path correct. 8751 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg); 8752 } 8753 8754 if (mFactoryTest && pkg.requestedPermissions.contains( 8755 android.Manifest.permission.FACTORY_TEST)) { 8756 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 8757 } 8758 8759 if (isSystemApp(pkg)) { 8760 pkgSetting.isOrphaned = true; 8761 } 8762 8763 // Take care of first install / last update times. 8764 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 8765 if (currentTime != 0) { 8766 if (pkgSetting.firstInstallTime == 0) { 8767 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8768 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) { 8769 pkgSetting.lastUpdateTime = currentTime; 8770 } 8771 } else if (pkgSetting.firstInstallTime == 0) { 8772 // We need *something*. Take time time stamp of the file. 8773 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8774 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8775 if (scanFileTime != pkgSetting.timeStamp) { 8776 // A package on the system image has changed; consider this 8777 // to be an update. 8778 pkgSetting.lastUpdateTime = scanFileTime; 8779 } 8780 } 8781 pkgSetting.setTimeStamp(scanFileTime); 8782 8783 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8784 if (nonMutatedPs != null) { 8785 synchronized (mPackages) { 8786 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 8787 } 8788 } 8789 } else { 8790 // Modify state for the given package setting 8791 commitPackageSettings(pkg, pkgSetting, user, scanFlags, 8792 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/); 8793 } 8794 return pkg; 8795 } 8796 8797 /** 8798 * Applies policy to the parsed package based upon the given policy flags. 8799 * Ensures the package is in a good state. 8800 * <p> 8801 * Implementation detail: This method must NOT have any side effect. It would 8802 * ideally be static, but, it requires locks to read system state. 8803 */ 8804 private void applyPolicy(PackageParser.Package pkg, int policyFlags) { 8805 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 8806 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 8807 if (pkg.applicationInfo.isDirectBootAware()) { 8808 // we're direct boot aware; set for all components 8809 for (PackageParser.Service s : pkg.services) { 8810 s.info.encryptionAware = s.info.directBootAware = true; 8811 } 8812 for (PackageParser.Provider p : pkg.providers) { 8813 p.info.encryptionAware = p.info.directBootAware = true; 8814 } 8815 for (PackageParser.Activity a : pkg.activities) { 8816 a.info.encryptionAware = a.info.directBootAware = true; 8817 } 8818 for (PackageParser.Activity r : pkg.receivers) { 8819 r.info.encryptionAware = r.info.directBootAware = true; 8820 } 8821 } 8822 } else { 8823 // Only allow system apps to be flagged as core apps. 8824 pkg.coreApp = false; 8825 // clear flags not applicable to regular apps 8826 pkg.applicationInfo.privateFlags &= 8827 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 8828 pkg.applicationInfo.privateFlags &= 8829 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 8830 } 8831 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 8832 8833 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 8834 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 8835 } 8836 8837 if (!isSystemApp(pkg)) { 8838 // Only system apps can use these features. 8839 pkg.mOriginalPackages = null; 8840 pkg.mRealPackage = null; 8841 pkg.mAdoptPermissions = null; 8842 } 8843 } 8844 8845 /** 8846 * Asserts the parsed package is valid according to teh given policy. If the 8847 * package is invalid, for whatever reason, throws {@link PackgeManagerException}. 8848 * <p> 8849 * Implementation detail: This method must NOT have any side effects. It would 8850 * ideally be static, but, it requires locks to read system state. 8851 * 8852 * @throws PackageManagerException If the package fails any of the validation checks 8853 */ 8854 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags) 8855 throws PackageManagerException { 8856 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 8857 assertCodePolicy(pkg); 8858 } 8859 8860 if (pkg.applicationInfo.getCodePath() == null || 8861 pkg.applicationInfo.getResourcePath() == null) { 8862 // Bail out. The resource and code paths haven't been set. 8863 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8864 "Code and resource paths haven't been set correctly"); 8865 } 8866 8867 // Make sure we're not adding any bogus keyset info 8868 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8869 ksms.assertScannedPackageValid(pkg); 8870 8871 synchronized (mPackages) { 8872 // The special "android" package can only be defined once 8873 if (pkg.packageName.equals("android")) { 8874 if (mAndroidApplication != null) { 8875 Slog.w(TAG, "*************************************************"); 8876 Slog.w(TAG, "Core android package being redefined. Skipping."); 8877 Slog.w(TAG, " codePath=" + pkg.codePath); 8878 Slog.w(TAG, "*************************************************"); 8879 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8880 "Core android package being redefined. Skipping."); 8881 } 8882 } 8883 8884 // A package name must be unique; don't allow duplicates 8885 if (mPackages.containsKey(pkg.packageName) 8886 || mSharedLibraries.containsKey(pkg.packageName)) { 8887 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8888 "Application package " + pkg.packageName 8889 + " already installed. Skipping duplicate."); 8890 } 8891 8892 // Only privileged apps and updated privileged apps can add child packages. 8893 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 8894 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 8895 throw new PackageManagerException("Only privileged apps can add child " 8896 + "packages. Ignoring package " + pkg.packageName); 8897 } 8898 final int childCount = pkg.childPackages.size(); 8899 for (int i = 0; i < childCount; i++) { 8900 PackageParser.Package childPkg = pkg.childPackages.get(i); 8901 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 8902 childPkg.packageName)) { 8903 throw new PackageManagerException("Can't override child of " 8904 + "another disabled app. Ignoring package " + pkg.packageName); 8905 } 8906 } 8907 } 8908 8909 // If we're only installing presumed-existing packages, require that the 8910 // scanned APK is both already known and at the path previously established 8911 // for it. Previously unknown packages we pick up normally, but if we have an 8912 // a priori expectation about this package's install presence, enforce it. 8913 // With a singular exception for new system packages. When an OTA contains 8914 // a new system package, we allow the codepath to change from a system location 8915 // to the user-installed location. If we don't allow this change, any newer, 8916 // user-installed version of the application will be ignored. 8917 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 8918 if (mExpectingBetter.containsKey(pkg.packageName)) { 8919 logCriticalInfo(Log.WARN, 8920 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 8921 } else { 8922 PackageSetting known = mSettings.getPackageLPr(pkg.packageName); 8923 if (known != null) { 8924 if (DEBUG_PACKAGE_SCANNING) { 8925 Log.d(TAG, "Examining " + pkg.codePath 8926 + " and requiring known paths " + known.codePathString 8927 + " & " + known.resourcePathString); 8928 } 8929 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 8930 || !pkg.applicationInfo.getResourcePath().equals( 8931 known.resourcePathString)) { 8932 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 8933 "Application package " + pkg.packageName 8934 + " found at " + pkg.applicationInfo.getCodePath() 8935 + " but expected at " + known.codePathString 8936 + "; ignoring."); 8937 } 8938 } 8939 } 8940 } 8941 8942 // Verify that this new package doesn't have any content providers 8943 // that conflict with existing packages. Only do this if the 8944 // package isn't already installed, since we don't want to break 8945 // things that are installed. 8946 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 8947 final int N = pkg.providers.size(); 8948 int i; 8949 for (i=0; i<N; i++) { 8950 PackageParser.Provider p = pkg.providers.get(i); 8951 if (p.info.authority != null) { 8952 String names[] = p.info.authority.split(";"); 8953 for (int j = 0; j < names.length; j++) { 8954 if (mProvidersByAuthority.containsKey(names[j])) { 8955 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8956 final String otherPackageName = 8957 ((other != null && other.getComponentName() != null) ? 8958 other.getComponentName().getPackageName() : "?"); 8959 throw new PackageManagerException( 8960 INSTALL_FAILED_CONFLICTING_PROVIDER, 8961 "Can't install because provider name " + names[j] 8962 + " (in package " + pkg.applicationInfo.packageName 8963 + ") is already used by " + otherPackageName); 8964 } 8965 } 8966 } 8967 } 8968 } 8969 } 8970 } 8971 8972 /** 8973 * Adds a scanned package to the system. When this method is finished, the package will 8974 * be available for query, resolution, etc... 8975 */ 8976 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting, 8977 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException { 8978 final String pkgName = pkg.packageName; 8979 if (mCustomResolverComponentName != null && 8980 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 8981 setUpCustomResolverActivity(pkg); 8982 } 8983 8984 if (pkg.packageName.equals("android")) { 8985 synchronized (mPackages) { 8986 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8987 // Set up information for our fall-back user intent resolution activity. 8988 mPlatformPackage = pkg; 8989 pkg.mVersionCode = mSdkVersion; 8990 mAndroidApplication = pkg.applicationInfo; 8991 8992 if (!mResolverReplaced) { 8993 mResolveActivity.applicationInfo = mAndroidApplication; 8994 mResolveActivity.name = ResolverActivity.class.getName(); 8995 mResolveActivity.packageName = mAndroidApplication.packageName; 8996 mResolveActivity.processName = "system:ui"; 8997 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8998 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 8999 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 9000 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 9001 mResolveActivity.exported = true; 9002 mResolveActivity.enabled = true; 9003 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 9004 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 9005 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 9006 | ActivityInfo.CONFIG_SCREEN_LAYOUT 9007 | ActivityInfo.CONFIG_ORIENTATION 9008 | ActivityInfo.CONFIG_KEYBOARD 9009 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 9010 mResolveInfo.activityInfo = mResolveActivity; 9011 mResolveInfo.priority = 0; 9012 mResolveInfo.preferredOrder = 0; 9013 mResolveInfo.match = 0; 9014 mResolveComponentName = new ComponentName( 9015 mAndroidApplication.packageName, mResolveActivity.name); 9016 } 9017 } 9018 } 9019 } 9020 9021 ArrayList<PackageParser.Package> clientLibPkgs = null; 9022 // writer 9023 synchronized (mPackages) { 9024 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9025 // Only system apps can add new shared libraries. 9026 if (pkg.libraryNames != null) { 9027 for (int i=0; i<pkg.libraryNames.size(); i++) { 9028 String name = pkg.libraryNames.get(i); 9029 boolean allowed = false; 9030 if (pkg.isUpdatedSystemApp()) { 9031 // New library entries can only be added through the 9032 // system image. This is important to get rid of a lot 9033 // of nasty edge cases: for example if we allowed a non- 9034 // system update of the app to add a library, then uninstalling 9035 // the update would make the library go away, and assumptions 9036 // we made such as through app install filtering would now 9037 // have allowed apps on the device which aren't compatible 9038 // with it. Better to just have the restriction here, be 9039 // conservative, and create many fewer cases that can negatively 9040 // impact the user experience. 9041 final PackageSetting sysPs = mSettings 9042 .getDisabledSystemPkgLPr(pkg.packageName); 9043 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 9044 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 9045 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 9046 allowed = true; 9047 break; 9048 } 9049 } 9050 } 9051 } else { 9052 allowed = true; 9053 } 9054 if (allowed) { 9055 if (!mSharedLibraries.containsKey(name)) { 9056 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 9057 } else if (!name.equals(pkg.packageName)) { 9058 Slog.w(TAG, "Package " + pkg.packageName + " library " 9059 + name + " already exists; skipping"); 9060 } 9061 } else { 9062 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 9063 + name + " that is not declared on system image; skipping"); 9064 } 9065 } 9066 if ((scanFlags & SCAN_BOOTING) == 0) { 9067 // If we are not booting, we need to update any applications 9068 // that are clients of our shared library. If we are booting, 9069 // this will all be done once the scan is complete. 9070 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 9071 } 9072 } 9073 } 9074 } 9075 9076 if ((scanFlags & SCAN_BOOTING) != 0) { 9077 // No apps can run during boot scan, so they don't need to be frozen 9078 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 9079 // Caller asked to not kill app, so it's probably not frozen 9080 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 9081 // Caller asked us to ignore frozen check for some reason; they 9082 // probably didn't know the package name 9083 } else { 9084 // We're doing major surgery on this package, so it better be frozen 9085 // right now to keep it from launching 9086 checkPackageFrozen(pkgName); 9087 } 9088 9089 // Also need to kill any apps that are dependent on the library. 9090 if (clientLibPkgs != null) { 9091 for (int i=0; i<clientLibPkgs.size(); i++) { 9092 PackageParser.Package clientPkg = clientLibPkgs.get(i); 9093 killApplication(clientPkg.applicationInfo.packageName, 9094 clientPkg.applicationInfo.uid, "update lib"); 9095 } 9096 } 9097 9098 // writer 9099 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 9100 9101 boolean createIdmapFailed = false; 9102 synchronized (mPackages) { 9103 // We don't expect installation to fail beyond this point 9104 9105 if (pkgSetting.pkg != null) { 9106 // Note that |user| might be null during the initial boot scan. If a codePath 9107 // for an app has changed during a boot scan, it's due to an app update that's 9108 // part of the system partition and marker changes must be applied to all users. 9109 final int userId = ((user != null) ? user : UserHandle.ALL).getIdentifier(); 9110 final int[] userIds = resolveUserIds(userId); 9111 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, userIds); 9112 } 9113 9114 // Add the new setting to mSettings 9115 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 9116 // Add the new setting to mPackages 9117 mPackages.put(pkg.applicationInfo.packageName, pkg); 9118 // Make sure we don't accidentally delete its data. 9119 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 9120 while (iter.hasNext()) { 9121 PackageCleanItem item = iter.next(); 9122 if (pkgName.equals(item.packageName)) { 9123 iter.remove(); 9124 } 9125 } 9126 9127 // Add the package's KeySets to the global KeySetManagerService 9128 KeySetManagerService ksms = mSettings.mKeySetManagerService; 9129 ksms.addScannedPackageLPw(pkg); 9130 9131 int N = pkg.providers.size(); 9132 StringBuilder r = null; 9133 int i; 9134 for (i=0; i<N; i++) { 9135 PackageParser.Provider p = pkg.providers.get(i); 9136 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 9137 p.info.processName); 9138 mProviders.addProvider(p); 9139 p.syncable = p.info.isSyncable; 9140 if (p.info.authority != null) { 9141 String names[] = p.info.authority.split(";"); 9142 p.info.authority = null; 9143 for (int j = 0; j < names.length; j++) { 9144 if (j == 1 && p.syncable) { 9145 // We only want the first authority for a provider to possibly be 9146 // syncable, so if we already added this provider using a different 9147 // authority clear the syncable flag. We copy the provider before 9148 // changing it because the mProviders object contains a reference 9149 // to a provider that we don't want to change. 9150 // Only do this for the second authority since the resulting provider 9151 // object can be the same for all future authorities for this provider. 9152 p = new PackageParser.Provider(p); 9153 p.syncable = false; 9154 } 9155 if (!mProvidersByAuthority.containsKey(names[j])) { 9156 mProvidersByAuthority.put(names[j], p); 9157 if (p.info.authority == null) { 9158 p.info.authority = names[j]; 9159 } else { 9160 p.info.authority = p.info.authority + ";" + names[j]; 9161 } 9162 if (DEBUG_PACKAGE_SCANNING) { 9163 if (chatty) 9164 Log.d(TAG, "Registered content provider: " + names[j] 9165 + ", className = " + p.info.name + ", isSyncable = " 9166 + p.info.isSyncable); 9167 } 9168 } else { 9169 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 9170 Slog.w(TAG, "Skipping provider name " + names[j] + 9171 " (in package " + pkg.applicationInfo.packageName + 9172 "): name already used by " 9173 + ((other != null && other.getComponentName() != null) 9174 ? other.getComponentName().getPackageName() : "?")); 9175 } 9176 } 9177 } 9178 if (chatty) { 9179 if (r == null) { 9180 r = new StringBuilder(256); 9181 } else { 9182 r.append(' '); 9183 } 9184 r.append(p.info.name); 9185 } 9186 } 9187 if (r != null) { 9188 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 9189 } 9190 9191 N = pkg.services.size(); 9192 r = null; 9193 for (i=0; i<N; i++) { 9194 PackageParser.Service s = pkg.services.get(i); 9195 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 9196 s.info.processName); 9197 mServices.addService(s); 9198 if (chatty) { 9199 if (r == null) { 9200 r = new StringBuilder(256); 9201 } else { 9202 r.append(' '); 9203 } 9204 r.append(s.info.name); 9205 } 9206 } 9207 if (r != null) { 9208 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 9209 } 9210 9211 N = pkg.receivers.size(); 9212 r = null; 9213 for (i=0; i<N; i++) { 9214 PackageParser.Activity a = pkg.receivers.get(i); 9215 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 9216 a.info.processName); 9217 mReceivers.addActivity(a, "receiver"); 9218 if (chatty) { 9219 if (r == null) { 9220 r = new StringBuilder(256); 9221 } else { 9222 r.append(' '); 9223 } 9224 r.append(a.info.name); 9225 } 9226 } 9227 if (r != null) { 9228 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 9229 } 9230 9231 N = pkg.activities.size(); 9232 r = null; 9233 for (i=0; i<N; i++) { 9234 PackageParser.Activity a = pkg.activities.get(i); 9235 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 9236 a.info.processName); 9237 mActivities.addActivity(a, "activity"); 9238 if (chatty) { 9239 if (r == null) { 9240 r = new StringBuilder(256); 9241 } else { 9242 r.append(' '); 9243 } 9244 r.append(a.info.name); 9245 } 9246 } 9247 if (r != null) { 9248 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 9249 } 9250 9251 N = pkg.permissionGroups.size(); 9252 r = null; 9253 for (i=0; i<N; i++) { 9254 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 9255 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 9256 final String curPackageName = cur == null ? null : cur.info.packageName; 9257 // Dont allow ephemeral apps to define new permission groups. 9258 if (pkg.applicationInfo.isEphemeralApp()) { 9259 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 9260 + pg.info.packageName 9261 + " ignored: ephemeral apps cannot define new permission groups."); 9262 continue; 9263 } 9264 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 9265 if (cur == null || isPackageUpdate) { 9266 mPermissionGroups.put(pg.info.name, pg); 9267 if (chatty) { 9268 if (r == null) { 9269 r = new StringBuilder(256); 9270 } else { 9271 r.append(' '); 9272 } 9273 if (isPackageUpdate) { 9274 r.append("UPD:"); 9275 } 9276 r.append(pg.info.name); 9277 } 9278 } else { 9279 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 9280 + pg.info.packageName + " ignored: original from " 9281 + cur.info.packageName); 9282 if (chatty) { 9283 if (r == null) { 9284 r = new StringBuilder(256); 9285 } else { 9286 r.append(' '); 9287 } 9288 r.append("DUP:"); 9289 r.append(pg.info.name); 9290 } 9291 } 9292 } 9293 if (r != null) { 9294 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 9295 } 9296 9297 N = pkg.permissions.size(); 9298 r = null; 9299 for (i=0; i<N; i++) { 9300 PackageParser.Permission p = pkg.permissions.get(i); 9301 9302 // Dont allow ephemeral apps to define new permissions. 9303 if (pkg.applicationInfo.isEphemeralApp()) { 9304 Slog.w(TAG, "Permission " + p.info.name + " from package " 9305 + p.info.packageName 9306 + " ignored: ephemeral apps cannot define new permissions."); 9307 continue; 9308 } 9309 9310 // Assume by default that we did not install this permission into the system. 9311 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 9312 9313 // Now that permission groups have a special meaning, we ignore permission 9314 // groups for legacy apps to prevent unexpected behavior. In particular, 9315 // permissions for one app being granted to someone just becase they happen 9316 // to be in a group defined by another app (before this had no implications). 9317 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 9318 p.group = mPermissionGroups.get(p.info.group); 9319 // Warn for a permission in an unknown group. 9320 if (p.info.group != null && p.group == null) { 9321 Slog.w(TAG, "Permission " + p.info.name + " from package " 9322 + p.info.packageName + " in an unknown group " + p.info.group); 9323 } 9324 } 9325 9326 ArrayMap<String, BasePermission> permissionMap = 9327 p.tree ? mSettings.mPermissionTrees 9328 : mSettings.mPermissions; 9329 BasePermission bp = permissionMap.get(p.info.name); 9330 9331 // Allow system apps to redefine non-system permissions 9332 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 9333 final boolean currentOwnerIsSystem = (bp.perm != null 9334 && isSystemApp(bp.perm.owner)); 9335 if (isSystemApp(p.owner)) { 9336 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 9337 // It's a built-in permission and no owner, take ownership now 9338 bp.packageSetting = pkgSetting; 9339 bp.perm = p; 9340 bp.uid = pkg.applicationInfo.uid; 9341 bp.sourcePackage = p.info.packageName; 9342 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 9343 } else if (!currentOwnerIsSystem) { 9344 String msg = "New decl " + p.owner + " of permission " 9345 + p.info.name + " is system; overriding " + bp.sourcePackage; 9346 reportSettingsProblem(Log.WARN, msg); 9347 bp = null; 9348 } 9349 } 9350 } 9351 9352 if (bp == null) { 9353 bp = new BasePermission(p.info.name, p.info.packageName, 9354 BasePermission.TYPE_NORMAL); 9355 permissionMap.put(p.info.name, bp); 9356 } 9357 9358 if (bp.perm == null) { 9359 if (bp.sourcePackage == null 9360 || bp.sourcePackage.equals(p.info.packageName)) { 9361 BasePermission tree = findPermissionTreeLP(p.info.name); 9362 if (tree == null 9363 || tree.sourcePackage.equals(p.info.packageName)) { 9364 bp.packageSetting = pkgSetting; 9365 bp.perm = p; 9366 bp.uid = pkg.applicationInfo.uid; 9367 bp.sourcePackage = p.info.packageName; 9368 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 9369 if (chatty) { 9370 if (r == null) { 9371 r = new StringBuilder(256); 9372 } else { 9373 r.append(' '); 9374 } 9375 r.append(p.info.name); 9376 } 9377 } else { 9378 Slog.w(TAG, "Permission " + p.info.name + " from package " 9379 + p.info.packageName + " ignored: base tree " 9380 + tree.name + " is from package " 9381 + tree.sourcePackage); 9382 } 9383 } else { 9384 Slog.w(TAG, "Permission " + p.info.name + " from package " 9385 + p.info.packageName + " ignored: original from " 9386 + bp.sourcePackage); 9387 } 9388 } else if (chatty) { 9389 if (r == null) { 9390 r = new StringBuilder(256); 9391 } else { 9392 r.append(' '); 9393 } 9394 r.append("DUP:"); 9395 r.append(p.info.name); 9396 } 9397 if (bp.perm == p) { 9398 bp.protectionLevel = p.info.protectionLevel; 9399 } 9400 } 9401 9402 if (r != null) { 9403 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 9404 } 9405 9406 N = pkg.instrumentation.size(); 9407 r = null; 9408 for (i=0; i<N; i++) { 9409 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9410 a.info.packageName = pkg.applicationInfo.packageName; 9411 a.info.sourceDir = pkg.applicationInfo.sourceDir; 9412 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 9413 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 9414 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 9415 a.info.dataDir = pkg.applicationInfo.dataDir; 9416 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 9417 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 9418 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 9419 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 9420 mInstrumentation.put(a.getComponentName(), a); 9421 if (chatty) { 9422 if (r == null) { 9423 r = new StringBuilder(256); 9424 } else { 9425 r.append(' '); 9426 } 9427 r.append(a.info.name); 9428 } 9429 } 9430 if (r != null) { 9431 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 9432 } 9433 9434 if (pkg.protectedBroadcasts != null) { 9435 N = pkg.protectedBroadcasts.size(); 9436 for (i=0; i<N; i++) { 9437 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 9438 } 9439 } 9440 9441 // Create idmap files for pairs of (packages, overlay packages). 9442 // Note: "android", ie framework-res.apk, is handled by native layers. 9443 if (pkg.mOverlayTarget != null) { 9444 // This is an overlay package. 9445 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 9446 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 9447 mOverlays.put(pkg.mOverlayTarget, 9448 new ArrayMap<String, PackageParser.Package>()); 9449 } 9450 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 9451 map.put(pkg.packageName, pkg); 9452 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 9453 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 9454 createIdmapFailed = true; 9455 } 9456 } 9457 } else if (mOverlays.containsKey(pkg.packageName) && 9458 !pkg.packageName.equals("android")) { 9459 // This is a regular package, with one or more known overlay packages. 9460 createIdmapsForPackageLI(pkg); 9461 } 9462 } 9463 9464 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9465 9466 if (createIdmapFailed) { 9467 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 9468 "scanPackageLI failed to createIdmap"); 9469 } 9470 } 9471 9472 private static void maybeRenameForeignDexMarkers(PackageParser.Package existing, 9473 PackageParser.Package update, int[] userIds) { 9474 if (existing.applicationInfo == null || update.applicationInfo == null) { 9475 // This isn't due to an app installation. 9476 return; 9477 } 9478 9479 final File oldCodePath = new File(existing.applicationInfo.getCodePath()); 9480 final File newCodePath = new File(update.applicationInfo.getCodePath()); 9481 9482 // The codePath hasn't changed, so there's nothing for us to do. 9483 if (Objects.equals(oldCodePath, newCodePath)) { 9484 return; 9485 } 9486 9487 File canonicalNewCodePath; 9488 try { 9489 canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath)); 9490 } catch (IOException e) { 9491 Slog.w(TAG, "Failed to get canonical path.", e); 9492 return; 9493 } 9494 9495 // This is a bit of a hack. The oldCodePath doesn't exist at this point (because 9496 // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume 9497 // that the last component of the path (i.e, the name) doesn't need canonicalization 9498 // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now 9499 // but may change in the future. Hopefully this function won't exist at that point. 9500 final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(), 9501 oldCodePath.getName()); 9502 9503 // Calculate the prefixes of the markers. These are just the paths with "/" replaced 9504 // with "@". 9505 String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@'); 9506 if (!oldMarkerPrefix.endsWith("@")) { 9507 oldMarkerPrefix += "@"; 9508 } 9509 String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@'); 9510 if (!newMarkerPrefix.endsWith("@")) { 9511 newMarkerPrefix += "@"; 9512 } 9513 9514 List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly(); 9515 List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size()); 9516 for (String updatedPath : updatedPaths) { 9517 String updatedPathName = new File(updatedPath).getName(); 9518 markerSuffixes.add(updatedPathName.replace('/', '@')); 9519 } 9520 9521 for (int userId : userIds) { 9522 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId); 9523 9524 for (String markerSuffix : markerSuffixes) { 9525 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix); 9526 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix); 9527 if (oldForeignUseMark.exists()) { 9528 try { 9529 Os.rename(oldForeignUseMark.getAbsolutePath(), 9530 newForeignUseMark.getAbsolutePath()); 9531 } catch (ErrnoException e) { 9532 Slog.w(TAG, "Failed to rename foreign use marker", e); 9533 oldForeignUseMark.delete(); 9534 } 9535 } 9536 } 9537 } 9538 } 9539 9540 /** 9541 * Derive the ABI of a non-system package located at {@code scanFile}. This information 9542 * is derived purely on the basis of the contents of {@code scanFile} and 9543 * {@code cpuAbiOverride}. 9544 * 9545 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 9546 */ 9547 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile, 9548 String cpuAbiOverride, boolean extractLibs, 9549 File appLib32InstallDir) 9550 throws PackageManagerException { 9551 // Give ourselves some initial paths; we'll come back for another 9552 // pass once we've determined ABI below. 9553 setNativeLibraryPaths(pkg, appLib32InstallDir); 9554 9555 // We would never need to extract libs for forward-locked and external packages, 9556 // since the container service will do it for us. We shouldn't attempt to 9557 // extract libs from system app when it was not updated. 9558 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 9559 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 9560 extractLibs = false; 9561 } 9562 9563 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 9564 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 9565 9566 NativeLibraryHelper.Handle handle = null; 9567 try { 9568 handle = NativeLibraryHelper.Handle.create(pkg); 9569 // TODO(multiArch): This can be null for apps that didn't go through the 9570 // usual installation process. We can calculate it again, like we 9571 // do during install time. 9572 // 9573 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 9574 // unnecessary. 9575 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 9576 9577 // Null out the abis so that they can be recalculated. 9578 pkg.applicationInfo.primaryCpuAbi = null; 9579 pkg.applicationInfo.secondaryCpuAbi = null; 9580 if (isMultiArch(pkg.applicationInfo)) { 9581 // Warn if we've set an abiOverride for multi-lib packages.. 9582 // By definition, we need to copy both 32 and 64 bit libraries for 9583 // such packages. 9584 if (pkg.cpuAbiOverride != null 9585 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 9586 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 9587 } 9588 9589 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 9590 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 9591 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 9592 if (extractLibs) { 9593 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9594 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9595 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 9596 useIsaSpecificSubdirs); 9597 } else { 9598 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9599 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 9600 } 9601 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9602 } 9603 9604 maybeThrowExceptionForMultiArchCopy( 9605 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 9606 9607 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 9608 if (extractLibs) { 9609 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9610 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9611 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 9612 useIsaSpecificSubdirs); 9613 } else { 9614 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9615 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 9616 } 9617 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9618 } 9619 9620 maybeThrowExceptionForMultiArchCopy( 9621 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 9622 9623 if (abi64 >= 0) { 9624 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 9625 } 9626 9627 if (abi32 >= 0) { 9628 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 9629 if (abi64 >= 0) { 9630 if (pkg.use32bitAbi) { 9631 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 9632 pkg.applicationInfo.primaryCpuAbi = abi; 9633 } else { 9634 pkg.applicationInfo.secondaryCpuAbi = abi; 9635 } 9636 } else { 9637 pkg.applicationInfo.primaryCpuAbi = abi; 9638 } 9639 } 9640 9641 } else { 9642 String[] abiList = (cpuAbiOverride != null) ? 9643 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 9644 9645 // Enable gross and lame hacks for apps that are built with old 9646 // SDK tools. We must scan their APKs for renderscript bitcode and 9647 // not launch them if it's present. Don't bother checking on devices 9648 // that don't have 64 bit support. 9649 boolean needsRenderScriptOverride = false; 9650 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 9651 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 9652 abiList = Build.SUPPORTED_32_BIT_ABIS; 9653 needsRenderScriptOverride = true; 9654 } 9655 9656 final int copyRet; 9657 if (extractLibs) { 9658 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9659 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9660 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 9661 } else { 9662 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9663 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 9664 } 9665 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9666 9667 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 9668 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 9669 "Error unpackaging native libs for app, errorCode=" + copyRet); 9670 } 9671 9672 if (copyRet >= 0) { 9673 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 9674 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 9675 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 9676 } else if (needsRenderScriptOverride) { 9677 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 9678 } 9679 } 9680 } catch (IOException ioe) { 9681 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 9682 } finally { 9683 IoUtils.closeQuietly(handle); 9684 } 9685 9686 // Now that we've calculated the ABIs and determined if it's an internal app, 9687 // we will go ahead and populate the nativeLibraryPath. 9688 setNativeLibraryPaths(pkg, appLib32InstallDir); 9689 } 9690 9691 /** 9692 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 9693 * i.e, so that all packages can be run inside a single process if required. 9694 * 9695 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 9696 * this function will either try and make the ABI for all packages in {@code packagesForUser} 9697 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 9698 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 9699 * updating a package that belongs to a shared user. 9700 * 9701 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 9702 * adds unnecessary complexity. 9703 */ 9704 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 9705 PackageParser.Package scannedPackage) { 9706 String requiredInstructionSet = null; 9707 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 9708 requiredInstructionSet = VMRuntime.getInstructionSet( 9709 scannedPackage.applicationInfo.primaryCpuAbi); 9710 } 9711 9712 PackageSetting requirer = null; 9713 for (PackageSetting ps : packagesForUser) { 9714 // If packagesForUser contains scannedPackage, we skip it. This will happen 9715 // when scannedPackage is an update of an existing package. Without this check, 9716 // we will never be able to change the ABI of any package belonging to a shared 9717 // user, even if it's compatible with other packages. 9718 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9719 if (ps.primaryCpuAbiString == null) { 9720 continue; 9721 } 9722 9723 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 9724 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 9725 // We have a mismatch between instruction sets (say arm vs arm64) warn about 9726 // this but there's not much we can do. 9727 String errorMessage = "Instruction set mismatch, " 9728 + ((requirer == null) ? "[caller]" : requirer) 9729 + " requires " + requiredInstructionSet + " whereas " + ps 9730 + " requires " + instructionSet; 9731 Slog.w(TAG, errorMessage); 9732 } 9733 9734 if (requiredInstructionSet == null) { 9735 requiredInstructionSet = instructionSet; 9736 requirer = ps; 9737 } 9738 } 9739 } 9740 9741 if (requiredInstructionSet != null) { 9742 String adjustedAbi; 9743 if (requirer != null) { 9744 // requirer != null implies that either scannedPackage was null or that scannedPackage 9745 // did not require an ABI, in which case we have to adjust scannedPackage to match 9746 // the ABI of the set (which is the same as requirer's ABI) 9747 adjustedAbi = requirer.primaryCpuAbiString; 9748 if (scannedPackage != null) { 9749 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 9750 } 9751 } else { 9752 // requirer == null implies that we're updating all ABIs in the set to 9753 // match scannedPackage. 9754 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 9755 } 9756 9757 for (PackageSetting ps : packagesForUser) { 9758 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9759 if (ps.primaryCpuAbiString != null) { 9760 continue; 9761 } 9762 9763 ps.primaryCpuAbiString = adjustedAbi; 9764 if (ps.pkg != null && ps.pkg.applicationInfo != null && 9765 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 9766 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 9767 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 9768 + " (requirer=" 9769 + (requirer == null ? "null" : requirer.pkg.packageName) 9770 + ", scannedPackage=" 9771 + (scannedPackage != null ? scannedPackage.packageName : "null") 9772 + ")"); 9773 try { 9774 mInstaller.rmdex(ps.codePathString, 9775 getDexCodeInstructionSet(getPreferredInstructionSet())); 9776 } catch (InstallerException ignored) { 9777 } 9778 } 9779 } 9780 } 9781 } 9782 } 9783 9784 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 9785 synchronized (mPackages) { 9786 mResolverReplaced = true; 9787 // Set up information for custom user intent resolution activity. 9788 mResolveActivity.applicationInfo = pkg.applicationInfo; 9789 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 9790 mResolveActivity.packageName = pkg.applicationInfo.packageName; 9791 mResolveActivity.processName = pkg.applicationInfo.packageName; 9792 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9793 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 9794 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9795 mResolveActivity.theme = 0; 9796 mResolveActivity.exported = true; 9797 mResolveActivity.enabled = true; 9798 mResolveInfo.activityInfo = mResolveActivity; 9799 mResolveInfo.priority = 0; 9800 mResolveInfo.preferredOrder = 0; 9801 mResolveInfo.match = 0; 9802 mResolveComponentName = mCustomResolverComponentName; 9803 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 9804 mResolveComponentName); 9805 } 9806 } 9807 9808 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 9809 if (installerComponent == null) { 9810 if (DEBUG_EPHEMERAL) { 9811 Slog.d(TAG, "Clear ephemeral installer activity"); 9812 } 9813 mEphemeralInstallerActivity.applicationInfo = null; 9814 return; 9815 } 9816 9817 if (DEBUG_EPHEMERAL) { 9818 Slog.d(TAG, "Set ephemeral installer activity: " + installerComponent); 9819 } 9820 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 9821 // Set up information for ephemeral installer activity 9822 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 9823 mEphemeralInstallerActivity.name = installerComponent.getClassName(); 9824 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 9825 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 9826 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9827 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 9828 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9829 mEphemeralInstallerActivity.theme = 0; 9830 mEphemeralInstallerActivity.exported = true; 9831 mEphemeralInstallerActivity.enabled = true; 9832 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 9833 mEphemeralInstallerInfo.priority = 0; 9834 mEphemeralInstallerInfo.preferredOrder = 1; 9835 mEphemeralInstallerInfo.isDefault = true; 9836 mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 9837 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 9838 } 9839 9840 private static String calculateBundledApkRoot(final String codePathString) { 9841 final File codePath = new File(codePathString); 9842 final File codeRoot; 9843 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 9844 codeRoot = Environment.getRootDirectory(); 9845 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 9846 codeRoot = Environment.getOemDirectory(); 9847 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 9848 codeRoot = Environment.getVendorDirectory(); 9849 } else { 9850 // Unrecognized code path; take its top real segment as the apk root: 9851 // e.g. /something/app/blah.apk => /something 9852 try { 9853 File f = codePath.getCanonicalFile(); 9854 File parent = f.getParentFile(); // non-null because codePath is a file 9855 File tmp; 9856 while ((tmp = parent.getParentFile()) != null) { 9857 f = parent; 9858 parent = tmp; 9859 } 9860 codeRoot = f; 9861 Slog.w(TAG, "Unrecognized code path " 9862 + codePath + " - using " + codeRoot); 9863 } catch (IOException e) { 9864 // Can't canonicalize the code path -- shenanigans? 9865 Slog.w(TAG, "Can't canonicalize code path " + codePath); 9866 return Environment.getRootDirectory().getPath(); 9867 } 9868 } 9869 return codeRoot.getPath(); 9870 } 9871 9872 /** 9873 * Derive and set the location of native libraries for the given package, 9874 * which varies depending on where and how the package was installed. 9875 */ 9876 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) { 9877 final ApplicationInfo info = pkg.applicationInfo; 9878 final String codePath = pkg.codePath; 9879 final File codeFile = new File(codePath); 9880 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 9881 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 9882 9883 info.nativeLibraryRootDir = null; 9884 info.nativeLibraryRootRequiresIsa = false; 9885 info.nativeLibraryDir = null; 9886 info.secondaryNativeLibraryDir = null; 9887 9888 if (isApkFile(codeFile)) { 9889 // Monolithic install 9890 if (bundledApp) { 9891 // If "/system/lib64/apkname" exists, assume that is the per-package 9892 // native library directory to use; otherwise use "/system/lib/apkname". 9893 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 9894 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 9895 getPrimaryInstructionSet(info)); 9896 9897 // This is a bundled system app so choose the path based on the ABI. 9898 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 9899 // is just the default path. 9900 final String apkName = deriveCodePathName(codePath); 9901 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 9902 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 9903 apkName).getAbsolutePath(); 9904 9905 if (info.secondaryCpuAbi != null) { 9906 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 9907 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 9908 secondaryLibDir, apkName).getAbsolutePath(); 9909 } 9910 } else if (asecApp) { 9911 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 9912 .getAbsolutePath(); 9913 } else { 9914 final String apkName = deriveCodePathName(codePath); 9915 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName) 9916 .getAbsolutePath(); 9917 } 9918 9919 info.nativeLibraryRootRequiresIsa = false; 9920 info.nativeLibraryDir = info.nativeLibraryRootDir; 9921 } else { 9922 // Cluster install 9923 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 9924 info.nativeLibraryRootRequiresIsa = true; 9925 9926 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 9927 getPrimaryInstructionSet(info)).getAbsolutePath(); 9928 9929 if (info.secondaryCpuAbi != null) { 9930 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 9931 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 9932 } 9933 } 9934 } 9935 9936 /** 9937 * Calculate the abis and roots for a bundled app. These can uniquely 9938 * be determined from the contents of the system partition, i.e whether 9939 * it contains 64 or 32 bit shared libraries etc. We do not validate any 9940 * of this information, and instead assume that the system was built 9941 * sensibly. 9942 */ 9943 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg, 9944 PackageSetting pkgSetting) { 9945 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 9946 9947 // If "/system/lib64/apkname" exists, assume that is the per-package 9948 // native library directory to use; otherwise use "/system/lib/apkname". 9949 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 9950 setBundledAppAbi(pkg, apkRoot, apkName); 9951 // pkgSetting might be null during rescan following uninstall of updates 9952 // to a bundled app, so accommodate that possibility. The settings in 9953 // that case will be established later from the parsed package. 9954 // 9955 // If the settings aren't null, sync them up with what we've just derived. 9956 // note that apkRoot isn't stored in the package settings. 9957 if (pkgSetting != null) { 9958 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9959 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9960 } 9961 } 9962 9963 /** 9964 * Deduces the ABI of a bundled app and sets the relevant fields on the 9965 * parsed pkg object. 9966 * 9967 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 9968 * under which system libraries are installed. 9969 * @param apkName the name of the installed package. 9970 */ 9971 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 9972 final File codeFile = new File(pkg.codePath); 9973 9974 final boolean has64BitLibs; 9975 final boolean has32BitLibs; 9976 if (isApkFile(codeFile)) { 9977 // Monolithic install 9978 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 9979 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 9980 } else { 9981 // Cluster install 9982 final File rootDir = new File(codeFile, LIB_DIR_NAME); 9983 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 9984 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 9985 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 9986 has64BitLibs = (new File(rootDir, isa)).exists(); 9987 } else { 9988 has64BitLibs = false; 9989 } 9990 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 9991 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 9992 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 9993 has32BitLibs = (new File(rootDir, isa)).exists(); 9994 } else { 9995 has32BitLibs = false; 9996 } 9997 } 9998 9999 if (has64BitLibs && !has32BitLibs) { 10000 // The package has 64 bit libs, but not 32 bit libs. Its primary 10001 // ABI should be 64 bit. We can safely assume here that the bundled 10002 // native libraries correspond to the most preferred ABI in the list. 10003 10004 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10005 pkg.applicationInfo.secondaryCpuAbi = null; 10006 } else if (has32BitLibs && !has64BitLibs) { 10007 // The package has 32 bit libs but not 64 bit libs. Its primary 10008 // ABI should be 32 bit. 10009 10010 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10011 pkg.applicationInfo.secondaryCpuAbi = null; 10012 } else if (has32BitLibs && has64BitLibs) { 10013 // The application has both 64 and 32 bit bundled libraries. We check 10014 // here that the app declares multiArch support, and warn if it doesn't. 10015 // 10016 // We will be lenient here and record both ABIs. The primary will be the 10017 // ABI that's higher on the list, i.e, a device that's configured to prefer 10018 // 64 bit apps will see a 64 bit primary ABI, 10019 10020 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 10021 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 10022 } 10023 10024 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 10025 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10026 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10027 } else { 10028 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 10029 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 10030 } 10031 } else { 10032 pkg.applicationInfo.primaryCpuAbi = null; 10033 pkg.applicationInfo.secondaryCpuAbi = null; 10034 } 10035 } 10036 10037 private void killApplication(String pkgName, int appId, String reason) { 10038 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 10039 } 10040 10041 private void killApplication(String pkgName, int appId, int userId, String reason) { 10042 // Request the ActivityManager to kill the process(only for existing packages) 10043 // so that we do not end up in a confused state while the user is still using the older 10044 // version of the application while the new one gets installed. 10045 final long token = Binder.clearCallingIdentity(); 10046 try { 10047 IActivityManager am = ActivityManager.getService(); 10048 if (am != null) { 10049 try { 10050 am.killApplication(pkgName, appId, userId, reason); 10051 } catch (RemoteException e) { 10052 } 10053 } 10054 } finally { 10055 Binder.restoreCallingIdentity(token); 10056 } 10057 } 10058 10059 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 10060 // Remove the parent package setting 10061 PackageSetting ps = (PackageSetting) pkg.mExtras; 10062 if (ps != null) { 10063 removePackageLI(ps, chatty); 10064 } 10065 // Remove the child package setting 10066 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10067 for (int i = 0; i < childCount; i++) { 10068 PackageParser.Package childPkg = pkg.childPackages.get(i); 10069 ps = (PackageSetting) childPkg.mExtras; 10070 if (ps != null) { 10071 removePackageLI(ps, chatty); 10072 } 10073 } 10074 } 10075 10076 void removePackageLI(PackageSetting ps, boolean chatty) { 10077 if (DEBUG_INSTALL) { 10078 if (chatty) 10079 Log.d(TAG, "Removing package " + ps.name); 10080 } 10081 10082 // writer 10083 synchronized (mPackages) { 10084 mPackages.remove(ps.name); 10085 final PackageParser.Package pkg = ps.pkg; 10086 if (pkg != null) { 10087 cleanPackageDataStructuresLILPw(pkg, chatty); 10088 } 10089 } 10090 } 10091 10092 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 10093 if (DEBUG_INSTALL) { 10094 if (chatty) 10095 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 10096 } 10097 10098 // writer 10099 synchronized (mPackages) { 10100 // Remove the parent package 10101 mPackages.remove(pkg.applicationInfo.packageName); 10102 cleanPackageDataStructuresLILPw(pkg, chatty); 10103 10104 // Remove the child packages 10105 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10106 for (int i = 0; i < childCount; i++) { 10107 PackageParser.Package childPkg = pkg.childPackages.get(i); 10108 mPackages.remove(childPkg.applicationInfo.packageName); 10109 cleanPackageDataStructuresLILPw(childPkg, chatty); 10110 } 10111 } 10112 } 10113 10114 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 10115 int N = pkg.providers.size(); 10116 StringBuilder r = null; 10117 int i; 10118 for (i=0; i<N; i++) { 10119 PackageParser.Provider p = pkg.providers.get(i); 10120 mProviders.removeProvider(p); 10121 if (p.info.authority == null) { 10122 10123 /* There was another ContentProvider with this authority when 10124 * this app was installed so this authority is null, 10125 * Ignore it as we don't have to unregister the provider. 10126 */ 10127 continue; 10128 } 10129 String names[] = p.info.authority.split(";"); 10130 for (int j = 0; j < names.length; j++) { 10131 if (mProvidersByAuthority.get(names[j]) == p) { 10132 mProvidersByAuthority.remove(names[j]); 10133 if (DEBUG_REMOVE) { 10134 if (chatty) 10135 Log.d(TAG, "Unregistered content provider: " + names[j] 10136 + ", className = " + p.info.name + ", isSyncable = " 10137 + p.info.isSyncable); 10138 } 10139 } 10140 } 10141 if (DEBUG_REMOVE && chatty) { 10142 if (r == null) { 10143 r = new StringBuilder(256); 10144 } else { 10145 r.append(' '); 10146 } 10147 r.append(p.info.name); 10148 } 10149 } 10150 if (r != null) { 10151 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 10152 } 10153 10154 N = pkg.services.size(); 10155 r = null; 10156 for (i=0; i<N; i++) { 10157 PackageParser.Service s = pkg.services.get(i); 10158 mServices.removeService(s); 10159 if (chatty) { 10160 if (r == null) { 10161 r = new StringBuilder(256); 10162 } else { 10163 r.append(' '); 10164 } 10165 r.append(s.info.name); 10166 } 10167 } 10168 if (r != null) { 10169 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 10170 } 10171 10172 N = pkg.receivers.size(); 10173 r = null; 10174 for (i=0; i<N; i++) { 10175 PackageParser.Activity a = pkg.receivers.get(i); 10176 mReceivers.removeActivity(a, "receiver"); 10177 if (DEBUG_REMOVE && chatty) { 10178 if (r == null) { 10179 r = new StringBuilder(256); 10180 } else { 10181 r.append(' '); 10182 } 10183 r.append(a.info.name); 10184 } 10185 } 10186 if (r != null) { 10187 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 10188 } 10189 10190 N = pkg.activities.size(); 10191 r = null; 10192 for (i=0; i<N; i++) { 10193 PackageParser.Activity a = pkg.activities.get(i); 10194 mActivities.removeActivity(a, "activity"); 10195 if (DEBUG_REMOVE && chatty) { 10196 if (r == null) { 10197 r = new StringBuilder(256); 10198 } else { 10199 r.append(' '); 10200 } 10201 r.append(a.info.name); 10202 } 10203 } 10204 if (r != null) { 10205 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 10206 } 10207 10208 N = pkg.permissions.size(); 10209 r = null; 10210 for (i=0; i<N; i++) { 10211 PackageParser.Permission p = pkg.permissions.get(i); 10212 BasePermission bp = mSettings.mPermissions.get(p.info.name); 10213 if (bp == null) { 10214 bp = mSettings.mPermissionTrees.get(p.info.name); 10215 } 10216 if (bp != null && bp.perm == p) { 10217 bp.perm = null; 10218 if (DEBUG_REMOVE && chatty) { 10219 if (r == null) { 10220 r = new StringBuilder(256); 10221 } else { 10222 r.append(' '); 10223 } 10224 r.append(p.info.name); 10225 } 10226 } 10227 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 10228 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 10229 if (appOpPkgs != null) { 10230 appOpPkgs.remove(pkg.packageName); 10231 } 10232 } 10233 } 10234 if (r != null) { 10235 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 10236 } 10237 10238 N = pkg.requestedPermissions.size(); 10239 r = null; 10240 for (i=0; i<N; i++) { 10241 String perm = pkg.requestedPermissions.get(i); 10242 BasePermission bp = mSettings.mPermissions.get(perm); 10243 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 10244 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 10245 if (appOpPkgs != null) { 10246 appOpPkgs.remove(pkg.packageName); 10247 if (appOpPkgs.isEmpty()) { 10248 mAppOpPermissionPackages.remove(perm); 10249 } 10250 } 10251 } 10252 } 10253 if (r != null) { 10254 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 10255 } 10256 10257 N = pkg.instrumentation.size(); 10258 r = null; 10259 for (i=0; i<N; i++) { 10260 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 10261 mInstrumentation.remove(a.getComponentName()); 10262 if (DEBUG_REMOVE && chatty) { 10263 if (r == null) { 10264 r = new StringBuilder(256); 10265 } else { 10266 r.append(' '); 10267 } 10268 r.append(a.info.name); 10269 } 10270 } 10271 if (r != null) { 10272 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 10273 } 10274 10275 r = null; 10276 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10277 // Only system apps can hold shared libraries. 10278 if (pkg.libraryNames != null) { 10279 for (i=0; i<pkg.libraryNames.size(); i++) { 10280 String name = pkg.libraryNames.get(i); 10281 SharedLibraryEntry cur = mSharedLibraries.get(name); 10282 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 10283 mSharedLibraries.remove(name); 10284 if (DEBUG_REMOVE && chatty) { 10285 if (r == null) { 10286 r = new StringBuilder(256); 10287 } else { 10288 r.append(' '); 10289 } 10290 r.append(name); 10291 } 10292 } 10293 } 10294 } 10295 } 10296 if (r != null) { 10297 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 10298 } 10299 } 10300 10301 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 10302 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 10303 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 10304 return true; 10305 } 10306 } 10307 return false; 10308 } 10309 10310 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 10311 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 10312 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 10313 10314 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 10315 // Update the parent permissions 10316 updatePermissionsLPw(pkg.packageName, pkg, flags); 10317 // Update the child permissions 10318 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 10319 for (int i = 0; i < childCount; i++) { 10320 PackageParser.Package childPkg = pkg.childPackages.get(i); 10321 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 10322 } 10323 } 10324 10325 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 10326 int flags) { 10327 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 10328 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 10329 } 10330 10331 private void updatePermissionsLPw(String changingPkg, 10332 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 10333 // Make sure there are no dangling permission trees. 10334 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 10335 while (it.hasNext()) { 10336 final BasePermission bp = it.next(); 10337 if (bp.packageSetting == null) { 10338 // We may not yet have parsed the package, so just see if 10339 // we still know about its settings. 10340 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 10341 } 10342 if (bp.packageSetting == null) { 10343 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 10344 + " from package " + bp.sourcePackage); 10345 it.remove(); 10346 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 10347 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 10348 Slog.i(TAG, "Removing old permission tree: " + bp.name 10349 + " from package " + bp.sourcePackage); 10350 flags |= UPDATE_PERMISSIONS_ALL; 10351 it.remove(); 10352 } 10353 } 10354 } 10355 10356 // Make sure all dynamic permissions have been assigned to a package, 10357 // and make sure there are no dangling permissions. 10358 it = mSettings.mPermissions.values().iterator(); 10359 while (it.hasNext()) { 10360 final BasePermission bp = it.next(); 10361 if (bp.type == BasePermission.TYPE_DYNAMIC) { 10362 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 10363 + bp.name + " pkg=" + bp.sourcePackage 10364 + " info=" + bp.pendingInfo); 10365 if (bp.packageSetting == null && bp.pendingInfo != null) { 10366 final BasePermission tree = findPermissionTreeLP(bp.name); 10367 if (tree != null && tree.perm != null) { 10368 bp.packageSetting = tree.packageSetting; 10369 bp.perm = new PackageParser.Permission(tree.perm.owner, 10370 new PermissionInfo(bp.pendingInfo)); 10371 bp.perm.info.packageName = tree.perm.info.packageName; 10372 bp.perm.info.name = bp.name; 10373 bp.uid = tree.uid; 10374 } 10375 } 10376 } 10377 if (bp.packageSetting == null) { 10378 // We may not yet have parsed the package, so just see if 10379 // we still know about its settings. 10380 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 10381 } 10382 if (bp.packageSetting == null) { 10383 Slog.w(TAG, "Removing dangling permission: " + bp.name 10384 + " from package " + bp.sourcePackage); 10385 it.remove(); 10386 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 10387 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 10388 Slog.i(TAG, "Removing old permission: " + bp.name 10389 + " from package " + bp.sourcePackage); 10390 flags |= UPDATE_PERMISSIONS_ALL; 10391 it.remove(); 10392 } 10393 } 10394 } 10395 10396 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 10397 // Now update the permissions for all packages, in particular 10398 // replace the granted permissions of the system packages. 10399 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 10400 for (PackageParser.Package pkg : mPackages.values()) { 10401 if (pkg != pkgInfo) { 10402 // Only replace for packages on requested volume 10403 final String volumeUuid = getVolumeUuidForPackage(pkg); 10404 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 10405 && Objects.equals(replaceVolumeUuid, volumeUuid); 10406 grantPermissionsLPw(pkg, replace, changingPkg); 10407 } 10408 } 10409 } 10410 10411 if (pkgInfo != null) { 10412 // Only replace for packages on requested volume 10413 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 10414 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 10415 && Objects.equals(replaceVolumeUuid, volumeUuid); 10416 grantPermissionsLPw(pkgInfo, replace, changingPkg); 10417 } 10418 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10419 } 10420 10421 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 10422 String packageOfInterest) { 10423 // IMPORTANT: There are two types of permissions: install and runtime. 10424 // Install time permissions are granted when the app is installed to 10425 // all device users and users added in the future. Runtime permissions 10426 // are granted at runtime explicitly to specific users. Normal and signature 10427 // protected permissions are install time permissions. Dangerous permissions 10428 // are install permissions if the app's target SDK is Lollipop MR1 or older, 10429 // otherwise they are runtime permissions. This function does not manage 10430 // runtime permissions except for the case an app targeting Lollipop MR1 10431 // being upgraded to target a newer SDK, in which case dangerous permissions 10432 // are transformed from install time to runtime ones. 10433 10434 final PackageSetting ps = (PackageSetting) pkg.mExtras; 10435 if (ps == null) { 10436 return; 10437 } 10438 10439 PermissionsState permissionsState = ps.getPermissionsState(); 10440 PermissionsState origPermissions = permissionsState; 10441 10442 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 10443 10444 boolean runtimePermissionsRevoked = false; 10445 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 10446 10447 boolean changedInstallPermission = false; 10448 10449 if (replace) { 10450 ps.installPermissionsFixed = false; 10451 if (!ps.isSharedUser()) { 10452 origPermissions = new PermissionsState(permissionsState); 10453 permissionsState.reset(); 10454 } else { 10455 // We need to know only about runtime permission changes since the 10456 // calling code always writes the install permissions state but 10457 // the runtime ones are written only if changed. The only cases of 10458 // changed runtime permissions here are promotion of an install to 10459 // runtime and revocation of a runtime from a shared user. 10460 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 10461 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 10462 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 10463 runtimePermissionsRevoked = true; 10464 } 10465 } 10466 } 10467 10468 permissionsState.setGlobalGids(mGlobalGids); 10469 10470 final int N = pkg.requestedPermissions.size(); 10471 for (int i=0; i<N; i++) { 10472 final String name = pkg.requestedPermissions.get(i); 10473 final BasePermission bp = mSettings.mPermissions.get(name); 10474 10475 if (DEBUG_INSTALL) { 10476 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 10477 } 10478 10479 if (bp == null || bp.packageSetting == null) { 10480 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10481 Slog.w(TAG, "Unknown permission " + name 10482 + " in package " + pkg.packageName); 10483 } 10484 continue; 10485 } 10486 10487 10488 // Limit ephemeral apps to ephemeral allowed permissions. 10489 if (pkg.applicationInfo.isEphemeralApp() && !bp.isEphemeral()) { 10490 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package " 10491 + pkg.packageName); 10492 continue; 10493 } 10494 10495 final String perm = bp.name; 10496 boolean allowedSig = false; 10497 int grant = GRANT_DENIED; 10498 10499 // Keep track of app op permissions. 10500 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 10501 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 10502 if (pkgs == null) { 10503 pkgs = new ArraySet<>(); 10504 mAppOpPermissionPackages.put(bp.name, pkgs); 10505 } 10506 pkgs.add(pkg.packageName); 10507 } 10508 10509 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 10510 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 10511 >= Build.VERSION_CODES.M; 10512 switch (level) { 10513 case PermissionInfo.PROTECTION_NORMAL: { 10514 // For all apps normal permissions are install time ones. 10515 grant = GRANT_INSTALL; 10516 } break; 10517 10518 case PermissionInfo.PROTECTION_DANGEROUS: { 10519 // If a permission review is required for legacy apps we represent 10520 // their permissions as always granted runtime ones since we need 10521 // to keep the review required permission flag per user while an 10522 // install permission's state is shared across all users. 10523 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) { 10524 // For legacy apps dangerous permissions are install time ones. 10525 grant = GRANT_INSTALL; 10526 } else if (origPermissions.hasInstallPermission(bp.name)) { 10527 // For legacy apps that became modern, install becomes runtime. 10528 grant = GRANT_UPGRADE; 10529 } else if (mPromoteSystemApps 10530 && isSystemApp(ps) 10531 && mExistingSystemPackages.contains(ps.name)) { 10532 // For legacy system apps, install becomes runtime. 10533 // We cannot check hasInstallPermission() for system apps since those 10534 // permissions were granted implicitly and not persisted pre-M. 10535 grant = GRANT_UPGRADE; 10536 } else { 10537 // For modern apps keep runtime permissions unchanged. 10538 grant = GRANT_RUNTIME; 10539 } 10540 } break; 10541 10542 case PermissionInfo.PROTECTION_SIGNATURE: { 10543 // For all apps signature permissions are install time ones. 10544 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 10545 if (allowedSig) { 10546 grant = GRANT_INSTALL; 10547 } 10548 } break; 10549 } 10550 10551 if (DEBUG_INSTALL) { 10552 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 10553 } 10554 10555 if (grant != GRANT_DENIED) { 10556 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 10557 // If this is an existing, non-system package, then 10558 // we can't add any new permissions to it. 10559 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 10560 // Except... if this is a permission that was added 10561 // to the platform (note: need to only do this when 10562 // updating the platform). 10563 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 10564 grant = GRANT_DENIED; 10565 } 10566 } 10567 } 10568 10569 switch (grant) { 10570 case GRANT_INSTALL: { 10571 // Revoke this as runtime permission to handle the case of 10572 // a runtime permission being downgraded to an install one. 10573 // Also in permission review mode we keep dangerous permissions 10574 // for legacy apps 10575 for (int userId : UserManagerService.getInstance().getUserIds()) { 10576 if (origPermissions.getRuntimePermissionState( 10577 bp.name, userId) != null) { 10578 // Revoke the runtime permission and clear the flags. 10579 origPermissions.revokeRuntimePermission(bp, userId); 10580 origPermissions.updatePermissionFlags(bp, userId, 10581 PackageManager.MASK_PERMISSION_FLAGS, 0); 10582 // If we revoked a permission permission, we have to write. 10583 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10584 changedRuntimePermissionUserIds, userId); 10585 } 10586 } 10587 // Grant an install permission. 10588 if (permissionsState.grantInstallPermission(bp) != 10589 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10590 changedInstallPermission = true; 10591 } 10592 } break; 10593 10594 case GRANT_RUNTIME: { 10595 // Grant previously granted runtime permissions. 10596 for (int userId : UserManagerService.getInstance().getUserIds()) { 10597 PermissionState permissionState = origPermissions 10598 .getRuntimePermissionState(bp.name, userId); 10599 int flags = permissionState != null 10600 ? permissionState.getFlags() : 0; 10601 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 10602 if (permissionsState.grantRuntimePermission(bp, userId) == 10603 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10604 // If we cannot put the permission as it was, we have to write. 10605 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10606 changedRuntimePermissionUserIds, userId); 10607 } 10608 // If the app supports runtime permissions no need for a review. 10609 if (mPermissionReviewRequired 10610 && appSupportsRuntimePermissions 10611 && (flags & PackageManager 10612 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 10613 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 10614 // Since we changed the flags, we have to write. 10615 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10616 changedRuntimePermissionUserIds, userId); 10617 } 10618 } else if (mPermissionReviewRequired 10619 && !appSupportsRuntimePermissions) { 10620 // For legacy apps that need a permission review, every new 10621 // runtime permission is granted but it is pending a review. 10622 // We also need to review only platform defined runtime 10623 // permissions as these are the only ones the platform knows 10624 // how to disable the API to simulate revocation as legacy 10625 // apps don't expect to run with revoked permissions. 10626 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 10627 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 10628 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 10629 // We changed the flags, hence have to write. 10630 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10631 changedRuntimePermissionUserIds, userId); 10632 } 10633 } 10634 if (permissionsState.grantRuntimePermission(bp, userId) 10635 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10636 // We changed the permission, hence have to write. 10637 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10638 changedRuntimePermissionUserIds, userId); 10639 } 10640 } 10641 // Propagate the permission flags. 10642 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 10643 } 10644 } break; 10645 10646 case GRANT_UPGRADE: { 10647 // Grant runtime permissions for a previously held install permission. 10648 PermissionState permissionState = origPermissions 10649 .getInstallPermissionState(bp.name); 10650 final int flags = permissionState != null ? permissionState.getFlags() : 0; 10651 10652 if (origPermissions.revokeInstallPermission(bp) 10653 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10654 // We will be transferring the permission flags, so clear them. 10655 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 10656 PackageManager.MASK_PERMISSION_FLAGS, 0); 10657 changedInstallPermission = true; 10658 } 10659 10660 // If the permission is not to be promoted to runtime we ignore it and 10661 // also its other flags as they are not applicable to install permissions. 10662 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 10663 for (int userId : currentUserIds) { 10664 if (permissionsState.grantRuntimePermission(bp, userId) != 10665 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10666 // Transfer the permission flags. 10667 permissionsState.updatePermissionFlags(bp, userId, 10668 flags, flags); 10669 // If we granted the permission, we have to write. 10670 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10671 changedRuntimePermissionUserIds, userId); 10672 } 10673 } 10674 } 10675 } break; 10676 10677 default: { 10678 if (packageOfInterest == null 10679 || packageOfInterest.equals(pkg.packageName)) { 10680 Slog.w(TAG, "Not granting permission " + perm 10681 + " to package " + pkg.packageName 10682 + " because it was previously installed without"); 10683 } 10684 } break; 10685 } 10686 } else { 10687 if (permissionsState.revokeInstallPermission(bp) != 10688 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10689 // Also drop the permission flags. 10690 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 10691 PackageManager.MASK_PERMISSION_FLAGS, 0); 10692 changedInstallPermission = true; 10693 Slog.i(TAG, "Un-granting permission " + perm 10694 + " from package " + pkg.packageName 10695 + " (protectionLevel=" + bp.protectionLevel 10696 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10697 + ")"); 10698 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 10699 // Don't print warning for app op permissions, since it is fine for them 10700 // not to be granted, there is a UI for the user to decide. 10701 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10702 Slog.w(TAG, "Not granting permission " + perm 10703 + " to package " + pkg.packageName 10704 + " (protectionLevel=" + bp.protectionLevel 10705 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10706 + ")"); 10707 } 10708 } 10709 } 10710 } 10711 10712 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 10713 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 10714 // This is the first that we have heard about this package, so the 10715 // permissions we have now selected are fixed until explicitly 10716 // changed. 10717 ps.installPermissionsFixed = true; 10718 } 10719 10720 // Persist the runtime permissions state for users with changes. If permissions 10721 // were revoked because no app in the shared user declares them we have to 10722 // write synchronously to avoid losing runtime permissions state. 10723 for (int userId : changedRuntimePermissionUserIds) { 10724 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 10725 } 10726 } 10727 10728 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 10729 boolean allowed = false; 10730 final int NP = PackageParser.NEW_PERMISSIONS.length; 10731 for (int ip=0; ip<NP; ip++) { 10732 final PackageParser.NewPermissionInfo npi 10733 = PackageParser.NEW_PERMISSIONS[ip]; 10734 if (npi.name.equals(perm) 10735 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 10736 allowed = true; 10737 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 10738 + pkg.packageName); 10739 break; 10740 } 10741 } 10742 return allowed; 10743 } 10744 10745 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 10746 BasePermission bp, PermissionsState origPermissions) { 10747 boolean privilegedPermission = (bp.protectionLevel 10748 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0; 10749 boolean privappPermissionsDisable = 10750 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE; 10751 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage); 10752 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName); 10753 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp() 10754 && !platformPackage && platformPermission) { 10755 ArraySet<String> wlPermissions = SystemConfig.getInstance() 10756 .getPrivAppPermissions(pkg.packageName); 10757 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm); 10758 if (!whitelisted) { 10759 Slog.w(TAG, "Privileged permission " + perm + " for package " 10760 + pkg.packageName + " - not in privapp-permissions whitelist"); 10761 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { 10762 return false; 10763 } 10764 } 10765 } 10766 boolean allowed = (compareSignatures( 10767 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 10768 == PackageManager.SIGNATURE_MATCH) 10769 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 10770 == PackageManager.SIGNATURE_MATCH); 10771 if (!allowed && privilegedPermission) { 10772 if (isSystemApp(pkg)) { 10773 // For updated system applications, a system permission 10774 // is granted only if it had been defined by the original application. 10775 if (pkg.isUpdatedSystemApp()) { 10776 final PackageSetting sysPs = mSettings 10777 .getDisabledSystemPkgLPr(pkg.packageName); 10778 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 10779 // If the original was granted this permission, we take 10780 // that grant decision as read and propagate it to the 10781 // update. 10782 if (sysPs.isPrivileged()) { 10783 allowed = true; 10784 } 10785 } else { 10786 // The system apk may have been updated with an older 10787 // version of the one on the data partition, but which 10788 // granted a new system permission that it didn't have 10789 // before. In this case we do want to allow the app to 10790 // now get the new permission if the ancestral apk is 10791 // privileged to get it. 10792 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 10793 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 10794 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 10795 allowed = true; 10796 break; 10797 } 10798 } 10799 } 10800 // Also if a privileged parent package on the system image or any of 10801 // its children requested a privileged permission, the updated child 10802 // packages can also get the permission. 10803 if (pkg.parentPackage != null) { 10804 final PackageSetting disabledSysParentPs = mSettings 10805 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 10806 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 10807 && disabledSysParentPs.isPrivileged()) { 10808 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 10809 allowed = true; 10810 } else if (disabledSysParentPs.pkg.childPackages != null) { 10811 final int count = disabledSysParentPs.pkg.childPackages.size(); 10812 for (int i = 0; i < count; i++) { 10813 PackageParser.Package disabledSysChildPkg = 10814 disabledSysParentPs.pkg.childPackages.get(i); 10815 if (isPackageRequestingPermission(disabledSysChildPkg, 10816 perm)) { 10817 allowed = true; 10818 break; 10819 } 10820 } 10821 } 10822 } 10823 } 10824 } 10825 } else { 10826 allowed = isPrivilegedApp(pkg); 10827 } 10828 } 10829 } 10830 if (!allowed) { 10831 if (!allowed && (bp.protectionLevel 10832 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 10833 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 10834 // If this was a previously normal/dangerous permission that got moved 10835 // to a system permission as part of the runtime permission redesign, then 10836 // we still want to blindly grant it to old apps. 10837 allowed = true; 10838 } 10839 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 10840 && pkg.packageName.equals(mRequiredInstallerPackage)) { 10841 // If this permission is to be granted to the system installer and 10842 // this app is an installer, then it gets the permission. 10843 allowed = true; 10844 } 10845 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 10846 && pkg.packageName.equals(mRequiredVerifierPackage)) { 10847 // If this permission is to be granted to the system verifier and 10848 // this app is a verifier, then it gets the permission. 10849 allowed = true; 10850 } 10851 if (!allowed && (bp.protectionLevel 10852 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 10853 && isSystemApp(pkg)) { 10854 // Any pre-installed system app is allowed to get this permission. 10855 allowed = true; 10856 } 10857 if (!allowed && (bp.protectionLevel 10858 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 10859 // For development permissions, a development permission 10860 // is granted only if it was already granted. 10861 allowed = origPermissions.hasInstallPermission(perm); 10862 } 10863 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 10864 && pkg.packageName.equals(mSetupWizardPackage)) { 10865 // If this permission is to be granted to the system setup wizard and 10866 // this app is a setup wizard, then it gets the permission. 10867 allowed = true; 10868 } 10869 } 10870 return allowed; 10871 } 10872 10873 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 10874 final int permCount = pkg.requestedPermissions.size(); 10875 for (int j = 0; j < permCount; j++) { 10876 String requestedPermission = pkg.requestedPermissions.get(j); 10877 if (permission.equals(requestedPermission)) { 10878 return true; 10879 } 10880 } 10881 return false; 10882 } 10883 10884 final class ActivityIntentResolver 10885 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 10886 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10887 boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) { 10888 if (!sUserManager.exists(userId)) return null; 10889 mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0) 10890 | (visibleToEphemeral ? PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY : 0) 10891 | (isEphemeral ? PackageManager.MATCH_EPHEMERAL : 0); 10892 return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral, 10893 isEphemeral, userId); 10894 } 10895 10896 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10897 int userId) { 10898 if (!sUserManager.exists(userId)) return null; 10899 mFlags = flags; 10900 return super.queryIntent(intent, resolvedType, 10901 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 10902 (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, 10903 (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId); 10904 } 10905 10906 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10907 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 10908 if (!sUserManager.exists(userId)) return null; 10909 if (packageActivities == null) { 10910 return null; 10911 } 10912 mFlags = flags; 10913 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10914 final boolean vislbleToEphemeral = 10915 (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0; 10916 final boolean isEphemeral = (flags & PackageManager.MATCH_EPHEMERAL) != 0; 10917 final int N = packageActivities.size(); 10918 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 10919 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 10920 10921 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 10922 for (int i = 0; i < N; ++i) { 10923 intentFilters = packageActivities.get(i).intents; 10924 if (intentFilters != null && intentFilters.size() > 0) { 10925 PackageParser.ActivityIntentInfo[] array = 10926 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 10927 intentFilters.toArray(array); 10928 listCut.add(array); 10929 } 10930 } 10931 return super.queryIntentFromList(intent, resolvedType, defaultOnly, 10932 vislbleToEphemeral, isEphemeral, listCut, userId); 10933 } 10934 10935 /** 10936 * Finds a privileged activity that matches the specified activity names. 10937 */ 10938 private PackageParser.Activity findMatchingActivity( 10939 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 10940 for (PackageParser.Activity sysActivity : activityList) { 10941 if (sysActivity.info.name.equals(activityInfo.name)) { 10942 return sysActivity; 10943 } 10944 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 10945 return sysActivity; 10946 } 10947 if (sysActivity.info.targetActivity != null) { 10948 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 10949 return sysActivity; 10950 } 10951 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 10952 return sysActivity; 10953 } 10954 } 10955 } 10956 return null; 10957 } 10958 10959 public class IterGenerator<E> { 10960 public Iterator<E> generate(ActivityIntentInfo info) { 10961 return null; 10962 } 10963 } 10964 10965 public class ActionIterGenerator extends IterGenerator<String> { 10966 @Override 10967 public Iterator<String> generate(ActivityIntentInfo info) { 10968 return info.actionsIterator(); 10969 } 10970 } 10971 10972 public class CategoriesIterGenerator extends IterGenerator<String> { 10973 @Override 10974 public Iterator<String> generate(ActivityIntentInfo info) { 10975 return info.categoriesIterator(); 10976 } 10977 } 10978 10979 public class SchemesIterGenerator extends IterGenerator<String> { 10980 @Override 10981 public Iterator<String> generate(ActivityIntentInfo info) { 10982 return info.schemesIterator(); 10983 } 10984 } 10985 10986 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 10987 @Override 10988 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 10989 return info.authoritiesIterator(); 10990 } 10991 } 10992 10993 /** 10994 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 10995 * MODIFIED. Do not pass in a list that should not be changed. 10996 */ 10997 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 10998 IterGenerator<T> generator, Iterator<T> searchIterator) { 10999 // loop through the set of actions; every one must be found in the intent filter 11000 while (searchIterator.hasNext()) { 11001 // we must have at least one filter in the list to consider a match 11002 if (intentList.size() == 0) { 11003 break; 11004 } 11005 11006 final T searchAction = searchIterator.next(); 11007 11008 // loop through the set of intent filters 11009 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 11010 while (intentIter.hasNext()) { 11011 final ActivityIntentInfo intentInfo = intentIter.next(); 11012 boolean selectionFound = false; 11013 11014 // loop through the intent filter's selection criteria; at least one 11015 // of them must match the searched criteria 11016 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 11017 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 11018 final T intentSelection = intentSelectionIter.next(); 11019 if (intentSelection != null && intentSelection.equals(searchAction)) { 11020 selectionFound = true; 11021 break; 11022 } 11023 } 11024 11025 // the selection criteria wasn't found in this filter's set; this filter 11026 // is not a potential match 11027 if (!selectionFound) { 11028 intentIter.remove(); 11029 } 11030 } 11031 } 11032 } 11033 11034 private boolean isProtectedAction(ActivityIntentInfo filter) { 11035 final Iterator<String> actionsIter = filter.actionsIterator(); 11036 while (actionsIter != null && actionsIter.hasNext()) { 11037 final String filterAction = actionsIter.next(); 11038 if (PROTECTED_ACTIONS.contains(filterAction)) { 11039 return true; 11040 } 11041 } 11042 return false; 11043 } 11044 11045 /** 11046 * Adjusts the priority of the given intent filter according to policy. 11047 * <p> 11048 * <ul> 11049 * <li>The priority for non privileged applications is capped to '0'</li> 11050 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 11051 * <li>The priority for unbundled updates to privileged applications is capped to the 11052 * priority defined on the system partition</li> 11053 * </ul> 11054 * <p> 11055 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 11056 * allowed to obtain any priority on any action. 11057 */ 11058 private void adjustPriority( 11059 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 11060 // nothing to do; priority is fine as-is 11061 if (intent.getPriority() <= 0) { 11062 return; 11063 } 11064 11065 final ActivityInfo activityInfo = intent.activity.info; 11066 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 11067 11068 final boolean privilegedApp = 11069 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 11070 if (!privilegedApp) { 11071 // non-privileged applications can never define a priority >0 11072 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 11073 + " package: " + applicationInfo.packageName 11074 + " activity: " + intent.activity.className 11075 + " origPrio: " + intent.getPriority()); 11076 intent.setPriority(0); 11077 return; 11078 } 11079 11080 if (systemActivities == null) { 11081 // the system package is not disabled; we're parsing the system partition 11082 if (isProtectedAction(intent)) { 11083 if (mDeferProtectedFilters) { 11084 // We can't deal with these just yet. No component should ever obtain a 11085 // >0 priority for a protected actions, with ONE exception -- the setup 11086 // wizard. The setup wizard, however, cannot be known until we're able to 11087 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 11088 // until all intent filters have been processed. Chicken, meet egg. 11089 // Let the filter temporarily have a high priority and rectify the 11090 // priorities after all system packages have been scanned. 11091 mProtectedFilters.add(intent); 11092 if (DEBUG_FILTERS) { 11093 Slog.i(TAG, "Protected action; save for later;" 11094 + " package: " + applicationInfo.packageName 11095 + " activity: " + intent.activity.className 11096 + " origPrio: " + intent.getPriority()); 11097 } 11098 return; 11099 } else { 11100 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 11101 Slog.i(TAG, "No setup wizard;" 11102 + " All protected intents capped to priority 0"); 11103 } 11104 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 11105 if (DEBUG_FILTERS) { 11106 Slog.i(TAG, "Found setup wizard;" 11107 + " allow priority " + intent.getPriority() + ";" 11108 + " package: " + intent.activity.info.packageName 11109 + " activity: " + intent.activity.className 11110 + " priority: " + intent.getPriority()); 11111 } 11112 // setup wizard gets whatever it wants 11113 return; 11114 } 11115 Slog.w(TAG, "Protected action; cap priority to 0;" 11116 + " package: " + intent.activity.info.packageName 11117 + " activity: " + intent.activity.className 11118 + " origPrio: " + intent.getPriority()); 11119 intent.setPriority(0); 11120 return; 11121 } 11122 } 11123 // privileged apps on the system image get whatever priority they request 11124 return; 11125 } 11126 11127 // privileged app unbundled update ... try to find the same activity 11128 final PackageParser.Activity foundActivity = 11129 findMatchingActivity(systemActivities, activityInfo); 11130 if (foundActivity == null) { 11131 // this is a new activity; it cannot obtain >0 priority 11132 if (DEBUG_FILTERS) { 11133 Slog.i(TAG, "New activity; cap priority to 0;" 11134 + " package: " + applicationInfo.packageName 11135 + " activity: " + intent.activity.className 11136 + " origPrio: " + intent.getPriority()); 11137 } 11138 intent.setPriority(0); 11139 return; 11140 } 11141 11142 // found activity, now check for filter equivalence 11143 11144 // a shallow copy is enough; we modify the list, not its contents 11145 final List<ActivityIntentInfo> intentListCopy = 11146 new ArrayList<>(foundActivity.intents); 11147 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 11148 11149 // find matching action subsets 11150 final Iterator<String> actionsIterator = intent.actionsIterator(); 11151 if (actionsIterator != null) { 11152 getIntentListSubset( 11153 intentListCopy, new ActionIterGenerator(), actionsIterator); 11154 if (intentListCopy.size() == 0) { 11155 // no more intents to match; we're not equivalent 11156 if (DEBUG_FILTERS) { 11157 Slog.i(TAG, "Mismatched action; cap priority to 0;" 11158 + " package: " + applicationInfo.packageName 11159 + " activity: " + intent.activity.className 11160 + " origPrio: " + intent.getPriority()); 11161 } 11162 intent.setPriority(0); 11163 return; 11164 } 11165 } 11166 11167 // find matching category subsets 11168 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 11169 if (categoriesIterator != null) { 11170 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 11171 categoriesIterator); 11172 if (intentListCopy.size() == 0) { 11173 // no more intents to match; we're not equivalent 11174 if (DEBUG_FILTERS) { 11175 Slog.i(TAG, "Mismatched category; cap priority to 0;" 11176 + " package: " + applicationInfo.packageName 11177 + " activity: " + intent.activity.className 11178 + " origPrio: " + intent.getPriority()); 11179 } 11180 intent.setPriority(0); 11181 return; 11182 } 11183 } 11184 11185 // find matching schemes subsets 11186 final Iterator<String> schemesIterator = intent.schemesIterator(); 11187 if (schemesIterator != null) { 11188 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 11189 schemesIterator); 11190 if (intentListCopy.size() == 0) { 11191 // no more intents to match; we're not equivalent 11192 if (DEBUG_FILTERS) { 11193 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 11194 + " package: " + applicationInfo.packageName 11195 + " activity: " + intent.activity.className 11196 + " origPrio: " + intent.getPriority()); 11197 } 11198 intent.setPriority(0); 11199 return; 11200 } 11201 } 11202 11203 // find matching authorities subsets 11204 final Iterator<IntentFilter.AuthorityEntry> 11205 authoritiesIterator = intent.authoritiesIterator(); 11206 if (authoritiesIterator != null) { 11207 getIntentListSubset(intentListCopy, 11208 new AuthoritiesIterGenerator(), 11209 authoritiesIterator); 11210 if (intentListCopy.size() == 0) { 11211 // no more intents to match; we're not equivalent 11212 if (DEBUG_FILTERS) { 11213 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 11214 + " package: " + applicationInfo.packageName 11215 + " activity: " + intent.activity.className 11216 + " origPrio: " + intent.getPriority()); 11217 } 11218 intent.setPriority(0); 11219 return; 11220 } 11221 } 11222 11223 // we found matching filter(s); app gets the max priority of all intents 11224 int cappedPriority = 0; 11225 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 11226 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 11227 } 11228 if (intent.getPriority() > cappedPriority) { 11229 if (DEBUG_FILTERS) { 11230 Slog.i(TAG, "Found matching filter(s);" 11231 + " cap priority to " + cappedPriority + ";" 11232 + " package: " + applicationInfo.packageName 11233 + " activity: " + intent.activity.className 11234 + " origPrio: " + intent.getPriority()); 11235 } 11236 intent.setPriority(cappedPriority); 11237 return; 11238 } 11239 // all this for nothing; the requested priority was <= what was on the system 11240 } 11241 11242 public final void addActivity(PackageParser.Activity a, String type) { 11243 mActivities.put(a.getComponentName(), a); 11244 if (DEBUG_SHOW_INFO) 11245 Log.v( 11246 TAG, " " + type + " " + 11247 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 11248 if (DEBUG_SHOW_INFO) 11249 Log.v(TAG, " Class=" + a.info.name); 11250 final int NI = a.intents.size(); 11251 for (int j=0; j<NI; j++) { 11252 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 11253 if ("activity".equals(type)) { 11254 final PackageSetting ps = 11255 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 11256 final List<PackageParser.Activity> systemActivities = 11257 ps != null && ps.pkg != null ? ps.pkg.activities : null; 11258 adjustPriority(systemActivities, intent); 11259 } 11260 if (DEBUG_SHOW_INFO) { 11261 Log.v(TAG, " IntentFilter:"); 11262 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11263 } 11264 if (!intent.debugCheck()) { 11265 Log.w(TAG, "==> For Activity " + a.info.name); 11266 } 11267 addFilter(intent); 11268 } 11269 } 11270 11271 public final void removeActivity(PackageParser.Activity a, String type) { 11272 mActivities.remove(a.getComponentName()); 11273 if (DEBUG_SHOW_INFO) { 11274 Log.v(TAG, " " + type + " " 11275 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 11276 : a.info.name) + ":"); 11277 Log.v(TAG, " Class=" + a.info.name); 11278 } 11279 final int NI = a.intents.size(); 11280 for (int j=0; j<NI; j++) { 11281 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 11282 if (DEBUG_SHOW_INFO) { 11283 Log.v(TAG, " IntentFilter:"); 11284 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11285 } 11286 removeFilter(intent); 11287 } 11288 } 11289 11290 @Override 11291 protected boolean allowFilterResult( 11292 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 11293 ActivityInfo filterAi = filter.activity.info; 11294 for (int i=dest.size()-1; i>=0; i--) { 11295 ActivityInfo destAi = dest.get(i).activityInfo; 11296 if (destAi.name == filterAi.name 11297 && destAi.packageName == filterAi.packageName) { 11298 return false; 11299 } 11300 } 11301 return true; 11302 } 11303 11304 @Override 11305 protected ActivityIntentInfo[] newArray(int size) { 11306 return new ActivityIntentInfo[size]; 11307 } 11308 11309 @Override 11310 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 11311 if (!sUserManager.exists(userId)) return true; 11312 PackageParser.Package p = filter.activity.owner; 11313 if (p != null) { 11314 PackageSetting ps = (PackageSetting)p.mExtras; 11315 if (ps != null) { 11316 // System apps are never considered stopped for purposes of 11317 // filtering, because there may be no way for the user to 11318 // actually re-launch them. 11319 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 11320 && ps.getStopped(userId); 11321 } 11322 } 11323 return false; 11324 } 11325 11326 @Override 11327 protected boolean isPackageForFilter(String packageName, 11328 PackageParser.ActivityIntentInfo info) { 11329 return packageName.equals(info.activity.owner.packageName); 11330 } 11331 11332 @Override 11333 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 11334 int match, int userId) { 11335 if (!sUserManager.exists(userId)) return null; 11336 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 11337 return null; 11338 } 11339 final PackageParser.Activity activity = info.activity; 11340 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 11341 if (ps == null) { 11342 return null; 11343 } 11344 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 11345 ps.readUserState(userId), userId); 11346 if (ai == null) { 11347 return null; 11348 } 11349 final ResolveInfo res = new ResolveInfo(); 11350 res.activityInfo = ai; 11351 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 11352 res.filter = info; 11353 } 11354 if (info != null) { 11355 res.handleAllWebDataURI = info.handleAllWebDataURI(); 11356 } 11357 res.priority = info.getPriority(); 11358 res.preferredOrder = activity.owner.mPreferredOrder; 11359 //System.out.println("Result: " + res.activityInfo.className + 11360 // " = " + res.priority); 11361 res.match = match; 11362 res.isDefault = info.hasDefault; 11363 res.labelRes = info.labelRes; 11364 res.nonLocalizedLabel = info.nonLocalizedLabel; 11365 if (userNeedsBadging(userId)) { 11366 res.noResourceId = true; 11367 } else { 11368 res.icon = info.icon; 11369 } 11370 res.iconResourceId = info.icon; 11371 res.system = res.activityInfo.applicationInfo.isSystemApp(); 11372 return res; 11373 } 11374 11375 @Override 11376 protected void sortResults(List<ResolveInfo> results) { 11377 Collections.sort(results, mResolvePrioritySorter); 11378 } 11379 11380 @Override 11381 protected void dumpFilter(PrintWriter out, String prefix, 11382 PackageParser.ActivityIntentInfo filter) { 11383 out.print(prefix); out.print( 11384 Integer.toHexString(System.identityHashCode(filter.activity))); 11385 out.print(' '); 11386 filter.activity.printComponentShortName(out); 11387 out.print(" filter "); 11388 out.println(Integer.toHexString(System.identityHashCode(filter))); 11389 } 11390 11391 @Override 11392 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 11393 return filter.activity; 11394 } 11395 11396 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11397 PackageParser.Activity activity = (PackageParser.Activity)label; 11398 out.print(prefix); out.print( 11399 Integer.toHexString(System.identityHashCode(activity))); 11400 out.print(' '); 11401 activity.printComponentShortName(out); 11402 if (count > 1) { 11403 out.print(" ("); out.print(count); out.print(" filters)"); 11404 } 11405 out.println(); 11406 } 11407 11408 // Keys are String (activity class name), values are Activity. 11409 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 11410 = new ArrayMap<ComponentName, PackageParser.Activity>(); 11411 private int mFlags; 11412 } 11413 11414 private final class ServiceIntentResolver 11415 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 11416 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11417 boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) { 11418 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 11419 return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral, 11420 isEphemeral, userId); 11421 } 11422 11423 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11424 int userId) { 11425 if (!sUserManager.exists(userId)) return null; 11426 mFlags = flags; 11427 return super.queryIntent(intent, resolvedType, 11428 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 11429 (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, 11430 (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId); 11431 } 11432 11433 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11434 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 11435 if (!sUserManager.exists(userId)) return null; 11436 if (packageServices == null) { 11437 return null; 11438 } 11439 mFlags = flags; 11440 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 11441 final boolean vislbleToEphemeral = 11442 (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0; 11443 final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0; 11444 final int N = packageServices.size(); 11445 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 11446 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 11447 11448 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 11449 for (int i = 0; i < N; ++i) { 11450 intentFilters = packageServices.get(i).intents; 11451 if (intentFilters != null && intentFilters.size() > 0) { 11452 PackageParser.ServiceIntentInfo[] array = 11453 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 11454 intentFilters.toArray(array); 11455 listCut.add(array); 11456 } 11457 } 11458 return super.queryIntentFromList(intent, resolvedType, defaultOnly, 11459 vislbleToEphemeral, isEphemeral, listCut, userId); 11460 } 11461 11462 public final void addService(PackageParser.Service s) { 11463 mServices.put(s.getComponentName(), s); 11464 if (DEBUG_SHOW_INFO) { 11465 Log.v(TAG, " " 11466 + (s.info.nonLocalizedLabel != null 11467 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 11468 Log.v(TAG, " Class=" + s.info.name); 11469 } 11470 final int NI = s.intents.size(); 11471 int j; 11472 for (j=0; j<NI; j++) { 11473 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 11474 if (DEBUG_SHOW_INFO) { 11475 Log.v(TAG, " IntentFilter:"); 11476 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11477 } 11478 if (!intent.debugCheck()) { 11479 Log.w(TAG, "==> For Service " + s.info.name); 11480 } 11481 addFilter(intent); 11482 } 11483 } 11484 11485 public final void removeService(PackageParser.Service s) { 11486 mServices.remove(s.getComponentName()); 11487 if (DEBUG_SHOW_INFO) { 11488 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 11489 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 11490 Log.v(TAG, " Class=" + s.info.name); 11491 } 11492 final int NI = s.intents.size(); 11493 int j; 11494 for (j=0; j<NI; j++) { 11495 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 11496 if (DEBUG_SHOW_INFO) { 11497 Log.v(TAG, " IntentFilter:"); 11498 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11499 } 11500 removeFilter(intent); 11501 } 11502 } 11503 11504 @Override 11505 protected boolean allowFilterResult( 11506 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 11507 ServiceInfo filterSi = filter.service.info; 11508 for (int i=dest.size()-1; i>=0; i--) { 11509 ServiceInfo destAi = dest.get(i).serviceInfo; 11510 if (destAi.name == filterSi.name 11511 && destAi.packageName == filterSi.packageName) { 11512 return false; 11513 } 11514 } 11515 return true; 11516 } 11517 11518 @Override 11519 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 11520 return new PackageParser.ServiceIntentInfo[size]; 11521 } 11522 11523 @Override 11524 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 11525 if (!sUserManager.exists(userId)) return true; 11526 PackageParser.Package p = filter.service.owner; 11527 if (p != null) { 11528 PackageSetting ps = (PackageSetting)p.mExtras; 11529 if (ps != null) { 11530 // System apps are never considered stopped for purposes of 11531 // filtering, because there may be no way for the user to 11532 // actually re-launch them. 11533 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11534 && ps.getStopped(userId); 11535 } 11536 } 11537 return false; 11538 } 11539 11540 @Override 11541 protected boolean isPackageForFilter(String packageName, 11542 PackageParser.ServiceIntentInfo info) { 11543 return packageName.equals(info.service.owner.packageName); 11544 } 11545 11546 @Override 11547 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 11548 int match, int userId) { 11549 if (!sUserManager.exists(userId)) return null; 11550 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 11551 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 11552 return null; 11553 } 11554 final PackageParser.Service service = info.service; 11555 PackageSetting ps = (PackageSetting) service.owner.mExtras; 11556 if (ps == null) { 11557 return null; 11558 } 11559 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 11560 ps.readUserState(userId), userId); 11561 if (si == null) { 11562 return null; 11563 } 11564 final ResolveInfo res = new ResolveInfo(); 11565 res.serviceInfo = si; 11566 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 11567 res.filter = filter; 11568 } 11569 res.priority = info.getPriority(); 11570 res.preferredOrder = service.owner.mPreferredOrder; 11571 res.match = match; 11572 res.isDefault = info.hasDefault; 11573 res.labelRes = info.labelRes; 11574 res.nonLocalizedLabel = info.nonLocalizedLabel; 11575 res.icon = info.icon; 11576 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 11577 return res; 11578 } 11579 11580 @Override 11581 protected void sortResults(List<ResolveInfo> results) { 11582 Collections.sort(results, mResolvePrioritySorter); 11583 } 11584 11585 @Override 11586 protected void dumpFilter(PrintWriter out, String prefix, 11587 PackageParser.ServiceIntentInfo filter) { 11588 out.print(prefix); out.print( 11589 Integer.toHexString(System.identityHashCode(filter.service))); 11590 out.print(' '); 11591 filter.service.printComponentShortName(out); 11592 out.print(" filter "); 11593 out.println(Integer.toHexString(System.identityHashCode(filter))); 11594 } 11595 11596 @Override 11597 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 11598 return filter.service; 11599 } 11600 11601 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11602 PackageParser.Service service = (PackageParser.Service)label; 11603 out.print(prefix); out.print( 11604 Integer.toHexString(System.identityHashCode(service))); 11605 out.print(' '); 11606 service.printComponentShortName(out); 11607 if (count > 1) { 11608 out.print(" ("); out.print(count); out.print(" filters)"); 11609 } 11610 out.println(); 11611 } 11612 11613// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 11614// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 11615// final List<ResolveInfo> retList = Lists.newArrayList(); 11616// while (i.hasNext()) { 11617// final ResolveInfo resolveInfo = (ResolveInfo) i; 11618// if (isEnabledLP(resolveInfo.serviceInfo)) { 11619// retList.add(resolveInfo); 11620// } 11621// } 11622// return retList; 11623// } 11624 11625 // Keys are String (activity class name), values are Activity. 11626 private final ArrayMap<ComponentName, PackageParser.Service> mServices 11627 = new ArrayMap<ComponentName, PackageParser.Service>(); 11628 private int mFlags; 11629 } 11630 11631 private final class ProviderIntentResolver 11632 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 11633 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11634 boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) { 11635 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 11636 return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral, 11637 isEphemeral, userId); 11638 } 11639 11640 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11641 int userId) { 11642 if (!sUserManager.exists(userId)) 11643 return null; 11644 mFlags = flags; 11645 return super.queryIntent(intent, resolvedType, 11646 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, 11647 (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, 11648 (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId); 11649 } 11650 11651 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11652 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 11653 if (!sUserManager.exists(userId)) 11654 return null; 11655 if (packageProviders == null) { 11656 return null; 11657 } 11658 mFlags = flags; 11659 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11660 final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0; 11661 final boolean vislbleToEphemeral = 11662 (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0; 11663 final int N = packageProviders.size(); 11664 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 11665 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 11666 11667 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 11668 for (int i = 0; i < N; ++i) { 11669 intentFilters = packageProviders.get(i).intents; 11670 if (intentFilters != null && intentFilters.size() > 0) { 11671 PackageParser.ProviderIntentInfo[] array = 11672 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 11673 intentFilters.toArray(array); 11674 listCut.add(array); 11675 } 11676 } 11677 return super.queryIntentFromList(intent, resolvedType, defaultOnly, 11678 vislbleToEphemeral, isEphemeral, listCut, userId); 11679 } 11680 11681 public final void addProvider(PackageParser.Provider p) { 11682 if (mProviders.containsKey(p.getComponentName())) { 11683 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 11684 return; 11685 } 11686 11687 mProviders.put(p.getComponentName(), p); 11688 if (DEBUG_SHOW_INFO) { 11689 Log.v(TAG, " " 11690 + (p.info.nonLocalizedLabel != null 11691 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11692 Log.v(TAG, " Class=" + p.info.name); 11693 } 11694 final int NI = p.intents.size(); 11695 int j; 11696 for (j = 0; j < NI; j++) { 11697 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11698 if (DEBUG_SHOW_INFO) { 11699 Log.v(TAG, " IntentFilter:"); 11700 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11701 } 11702 if (!intent.debugCheck()) { 11703 Log.w(TAG, "==> For Provider " + p.info.name); 11704 } 11705 addFilter(intent); 11706 } 11707 } 11708 11709 public final void removeProvider(PackageParser.Provider p) { 11710 mProviders.remove(p.getComponentName()); 11711 if (DEBUG_SHOW_INFO) { 11712 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 11713 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11714 Log.v(TAG, " Class=" + p.info.name); 11715 } 11716 final int NI = p.intents.size(); 11717 int j; 11718 for (j = 0; j < NI; j++) { 11719 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11720 if (DEBUG_SHOW_INFO) { 11721 Log.v(TAG, " IntentFilter:"); 11722 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11723 } 11724 removeFilter(intent); 11725 } 11726 } 11727 11728 @Override 11729 protected boolean allowFilterResult( 11730 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 11731 ProviderInfo filterPi = filter.provider.info; 11732 for (int i = dest.size() - 1; i >= 0; i--) { 11733 ProviderInfo destPi = dest.get(i).providerInfo; 11734 if (destPi.name == filterPi.name 11735 && destPi.packageName == filterPi.packageName) { 11736 return false; 11737 } 11738 } 11739 return true; 11740 } 11741 11742 @Override 11743 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 11744 return new PackageParser.ProviderIntentInfo[size]; 11745 } 11746 11747 @Override 11748 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 11749 if (!sUserManager.exists(userId)) 11750 return true; 11751 PackageParser.Package p = filter.provider.owner; 11752 if (p != null) { 11753 PackageSetting ps = (PackageSetting) p.mExtras; 11754 if (ps != null) { 11755 // System apps are never considered stopped for purposes of 11756 // filtering, because there may be no way for the user to 11757 // actually re-launch them. 11758 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11759 && ps.getStopped(userId); 11760 } 11761 } 11762 return false; 11763 } 11764 11765 @Override 11766 protected boolean isPackageForFilter(String packageName, 11767 PackageParser.ProviderIntentInfo info) { 11768 return packageName.equals(info.provider.owner.packageName); 11769 } 11770 11771 @Override 11772 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 11773 int match, int userId) { 11774 if (!sUserManager.exists(userId)) 11775 return null; 11776 final PackageParser.ProviderIntentInfo info = filter; 11777 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 11778 return null; 11779 } 11780 final PackageParser.Provider provider = info.provider; 11781 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 11782 if (ps == null) { 11783 return null; 11784 } 11785 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 11786 ps.readUserState(userId), userId); 11787 if (pi == null) { 11788 return null; 11789 } 11790 final ResolveInfo res = new ResolveInfo(); 11791 res.providerInfo = pi; 11792 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 11793 res.filter = filter; 11794 } 11795 res.priority = info.getPriority(); 11796 res.preferredOrder = provider.owner.mPreferredOrder; 11797 res.match = match; 11798 res.isDefault = info.hasDefault; 11799 res.labelRes = info.labelRes; 11800 res.nonLocalizedLabel = info.nonLocalizedLabel; 11801 res.icon = info.icon; 11802 res.system = res.providerInfo.applicationInfo.isSystemApp(); 11803 return res; 11804 } 11805 11806 @Override 11807 protected void sortResults(List<ResolveInfo> results) { 11808 Collections.sort(results, mResolvePrioritySorter); 11809 } 11810 11811 @Override 11812 protected void dumpFilter(PrintWriter out, String prefix, 11813 PackageParser.ProviderIntentInfo filter) { 11814 out.print(prefix); 11815 out.print( 11816 Integer.toHexString(System.identityHashCode(filter.provider))); 11817 out.print(' '); 11818 filter.provider.printComponentShortName(out); 11819 out.print(" filter "); 11820 out.println(Integer.toHexString(System.identityHashCode(filter))); 11821 } 11822 11823 @Override 11824 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 11825 return filter.provider; 11826 } 11827 11828 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11829 PackageParser.Provider provider = (PackageParser.Provider)label; 11830 out.print(prefix); out.print( 11831 Integer.toHexString(System.identityHashCode(provider))); 11832 out.print(' '); 11833 provider.printComponentShortName(out); 11834 if (count > 1) { 11835 out.print(" ("); out.print(count); out.print(" filters)"); 11836 } 11837 out.println(); 11838 } 11839 11840 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 11841 = new ArrayMap<ComponentName, PackageParser.Provider>(); 11842 private int mFlags; 11843 } 11844 11845 static final class EphemeralIntentResolver 11846 extends IntentResolver<EphemeralResponse, EphemeralResponse> { 11847 /** 11848 * The result that has the highest defined order. Ordering applies on a 11849 * per-package basis. Mapping is from package name to Pair of order and 11850 * EphemeralResolveInfo. 11851 * <p> 11852 * NOTE: This is implemented as a field variable for convenience and efficiency. 11853 * By having a field variable, we're able to track filter ordering as soon as 11854 * a non-zero order is defined. Otherwise, multiple loops across the result set 11855 * would be needed to apply ordering. If the intent resolver becomes re-entrant, 11856 * this needs to be contained entirely within {@link #filterResults()}. 11857 */ 11858 final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>(); 11859 11860 @Override 11861 protected EphemeralResponse[] newArray(int size) { 11862 return new EphemeralResponse[size]; 11863 } 11864 11865 @Override 11866 protected boolean isPackageForFilter(String packageName, EphemeralResponse responseObj) { 11867 return true; 11868 } 11869 11870 @Override 11871 protected EphemeralResponse newResult(EphemeralResponse responseObj, int match, 11872 int userId) { 11873 if (!sUserManager.exists(userId)) { 11874 return null; 11875 } 11876 final String packageName = responseObj.resolveInfo.getPackageName(); 11877 final Integer order = responseObj.getOrder(); 11878 final Pair<Integer, EphemeralResolveInfo> lastOrderResult = 11879 mOrderResult.get(packageName); 11880 // ordering is enabled and this item's order isn't high enough 11881 if (lastOrderResult != null && lastOrderResult.first >= order) { 11882 return null; 11883 } 11884 final EphemeralResolveInfo res = responseObj.resolveInfo; 11885 if (order > 0) { 11886 // non-zero order, enable ordering 11887 mOrderResult.put(packageName, new Pair<>(order, res)); 11888 } 11889 return responseObj; 11890 } 11891 11892 @Override 11893 protected void filterResults(List<EphemeralResponse> results) { 11894 // only do work if ordering is enabled [most of the time it won't be] 11895 if (mOrderResult.size() == 0) { 11896 return; 11897 } 11898 int resultSize = results.size(); 11899 for (int i = 0; i < resultSize; i++) { 11900 final EphemeralResolveInfo info = results.get(i).resolveInfo; 11901 final String packageName = info.getPackageName(); 11902 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName); 11903 if (savedInfo == null) { 11904 // package doesn't having ordering 11905 continue; 11906 } 11907 if (savedInfo.second == info) { 11908 // circled back to the highest ordered item; remove from order list 11909 mOrderResult.remove(savedInfo); 11910 if (mOrderResult.size() == 0) { 11911 // no more ordered items 11912 break; 11913 } 11914 continue; 11915 } 11916 // item has a worse order, remove it from the result list 11917 results.remove(i); 11918 resultSize--; 11919 i--; 11920 } 11921 } 11922 } 11923 11924 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 11925 new Comparator<ResolveInfo>() { 11926 public int compare(ResolveInfo r1, ResolveInfo r2) { 11927 int v1 = r1.priority; 11928 int v2 = r2.priority; 11929 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 11930 if (v1 != v2) { 11931 return (v1 > v2) ? -1 : 1; 11932 } 11933 v1 = r1.preferredOrder; 11934 v2 = r2.preferredOrder; 11935 if (v1 != v2) { 11936 return (v1 > v2) ? -1 : 1; 11937 } 11938 if (r1.isDefault != r2.isDefault) { 11939 return r1.isDefault ? -1 : 1; 11940 } 11941 v1 = r1.match; 11942 v2 = r2.match; 11943 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 11944 if (v1 != v2) { 11945 return (v1 > v2) ? -1 : 1; 11946 } 11947 if (r1.system != r2.system) { 11948 return r1.system ? -1 : 1; 11949 } 11950 if (r1.activityInfo != null) { 11951 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 11952 } 11953 if (r1.serviceInfo != null) { 11954 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 11955 } 11956 if (r1.providerInfo != null) { 11957 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 11958 } 11959 return 0; 11960 } 11961 }; 11962 11963 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 11964 new Comparator<ProviderInfo>() { 11965 public int compare(ProviderInfo p1, ProviderInfo p2) { 11966 final int v1 = p1.initOrder; 11967 final int v2 = p2.initOrder; 11968 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 11969 } 11970 }; 11971 11972 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 11973 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 11974 final int[] userIds) { 11975 mHandler.post(new Runnable() { 11976 @Override 11977 public void run() { 11978 try { 11979 final IActivityManager am = ActivityManager.getService(); 11980 if (am == null) return; 11981 final int[] resolvedUserIds; 11982 if (userIds == null) { 11983 resolvedUserIds = am.getRunningUserIds(); 11984 } else { 11985 resolvedUserIds = userIds; 11986 } 11987 for (int id : resolvedUserIds) { 11988 final Intent intent = new Intent(action, 11989 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 11990 if (extras != null) { 11991 intent.putExtras(extras); 11992 } 11993 if (targetPkg != null) { 11994 intent.setPackage(targetPkg); 11995 } 11996 // Modify the UID when posting to other users 11997 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 11998 if (uid > 0 && UserHandle.getUserId(uid) != id) { 11999 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 12000 intent.putExtra(Intent.EXTRA_UID, uid); 12001 } 12002 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 12003 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 12004 if (DEBUG_BROADCASTS) { 12005 RuntimeException here = new RuntimeException("here"); 12006 here.fillInStackTrace(); 12007 Slog.d(TAG, "Sending to user " + id + ": " 12008 + intent.toShortString(false, true, false, false) 12009 + " " + intent.getExtras(), here); 12010 } 12011 am.broadcastIntent(null, intent, null, finishedReceiver, 12012 0, null, null, null, android.app.AppOpsManager.OP_NONE, 12013 null, finishedReceiver != null, false, id); 12014 } 12015 } catch (RemoteException ex) { 12016 } 12017 } 12018 }); 12019 } 12020 12021 /** 12022 * Check if the external storage media is available. This is true if there 12023 * is a mounted external storage medium or if the external storage is 12024 * emulated. 12025 */ 12026 private boolean isExternalMediaAvailable() { 12027 return mMediaMounted || Environment.isExternalStorageEmulated(); 12028 } 12029 12030 @Override 12031 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 12032 // writer 12033 synchronized (mPackages) { 12034 if (!isExternalMediaAvailable()) { 12035 // If the external storage is no longer mounted at this point, 12036 // the caller may not have been able to delete all of this 12037 // packages files and can not delete any more. Bail. 12038 return null; 12039 } 12040 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 12041 if (lastPackage != null) { 12042 pkgs.remove(lastPackage); 12043 } 12044 if (pkgs.size() > 0) { 12045 return pkgs.get(0); 12046 } 12047 } 12048 return null; 12049 } 12050 12051 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 12052 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 12053 userId, andCode ? 1 : 0, packageName); 12054 if (mSystemReady) { 12055 msg.sendToTarget(); 12056 } else { 12057 if (mPostSystemReadyMessages == null) { 12058 mPostSystemReadyMessages = new ArrayList<>(); 12059 } 12060 mPostSystemReadyMessages.add(msg); 12061 } 12062 } 12063 12064 void startCleaningPackages() { 12065 // reader 12066 if (!isExternalMediaAvailable()) { 12067 return; 12068 } 12069 synchronized (mPackages) { 12070 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 12071 return; 12072 } 12073 } 12074 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 12075 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 12076 IActivityManager am = ActivityManager.getService(); 12077 if (am != null) { 12078 try { 12079 am.startService(null, intent, null, mContext.getOpPackageName(), 12080 UserHandle.USER_SYSTEM); 12081 } catch (RemoteException e) { 12082 } 12083 } 12084 } 12085 12086 @Override 12087 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 12088 int installFlags, String installerPackageName, int userId) { 12089 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 12090 12091 final int callingUid = Binder.getCallingUid(); 12092 enforceCrossUserPermission(callingUid, userId, 12093 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 12094 12095 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 12096 try { 12097 if (observer != null) { 12098 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 12099 } 12100 } catch (RemoteException re) { 12101 } 12102 return; 12103 } 12104 12105 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 12106 installFlags |= PackageManager.INSTALL_FROM_ADB; 12107 12108 } else { 12109 // Caller holds INSTALL_PACKAGES permission, so we're less strict 12110 // about installerPackageName. 12111 12112 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 12113 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 12114 } 12115 12116 UserHandle user; 12117 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 12118 user = UserHandle.ALL; 12119 } else { 12120 user = new UserHandle(userId); 12121 } 12122 12123 // Only system components can circumvent runtime permissions when installing. 12124 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 12125 && mContext.checkCallingOrSelfPermission(Manifest.permission 12126 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 12127 throw new SecurityException("You need the " 12128 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 12129 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 12130 } 12131 12132 final File originFile = new File(originPath); 12133 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 12134 12135 final Message msg = mHandler.obtainMessage(INIT_COPY); 12136 final VerificationInfo verificationInfo = new VerificationInfo( 12137 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 12138 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 12139 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 12140 null /*packageAbiOverride*/, null /*grantedPermissions*/, 12141 null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN); 12142 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 12143 msg.obj = params; 12144 12145 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 12146 System.identityHashCode(msg.obj)); 12147 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 12148 System.identityHashCode(msg.obj)); 12149 12150 mHandler.sendMessage(msg); 12151 } 12152 12153 void installStage(String packageName, File stagedDir, String stagedCid, 12154 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 12155 String installerPackageName, int installerUid, UserHandle user, 12156 Certificate[][] certificates) { 12157 if (DEBUG_EPHEMERAL) { 12158 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 12159 Slog.d(TAG, "Ephemeral install of " + packageName); 12160 } 12161 } 12162 final VerificationInfo verificationInfo = new VerificationInfo( 12163 sessionParams.originatingUri, sessionParams.referrerUri, 12164 sessionParams.originatingUid, installerUid); 12165 12166 final OriginInfo origin; 12167 if (stagedDir != null) { 12168 origin = OriginInfo.fromStagedFile(stagedDir); 12169 } else { 12170 origin = OriginInfo.fromStagedContainer(stagedCid); 12171 } 12172 12173 final Message msg = mHandler.obtainMessage(INIT_COPY); 12174 final InstallParams params = new InstallParams(origin, null, observer, 12175 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 12176 verificationInfo, user, sessionParams.abiOverride, 12177 sessionParams.grantedRuntimePermissions, certificates, sessionParams.installReason); 12178 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 12179 msg.obj = params; 12180 12181 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 12182 System.identityHashCode(msg.obj)); 12183 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 12184 System.identityHashCode(msg.obj)); 12185 12186 mHandler.sendMessage(msg); 12187 } 12188 12189 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 12190 int userId) { 12191 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 12192 sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId); 12193 } 12194 12195 private void sendPackageAddedForNewUsers(String packageName, boolean isSystem, 12196 int appId, int... userIds) { 12197 if (ArrayUtils.isEmpty(userIds)) { 12198 return; 12199 } 12200 Bundle extras = new Bundle(1); 12201 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast 12202 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId)); 12203 12204 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 12205 packageName, extras, 0, null, null, userIds); 12206 if (isSystem) { 12207 mHandler.post(() -> { 12208 for (int userId : userIds) { 12209 sendBootCompletedBroadcastToSystemApp(packageName, userId); 12210 } 12211 } 12212 ); 12213 } 12214 } 12215 12216 /** 12217 * The just-installed/enabled app is bundled on the system, so presumed to be able to run 12218 * automatically without needing an explicit launch. 12219 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones. 12220 */ 12221 private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) { 12222 // If user is not running, the app didn't miss any broadcast 12223 if (!mUserManagerInternal.isUserRunning(userId)) { 12224 return; 12225 } 12226 final IActivityManager am = ActivityManager.getService(); 12227 try { 12228 // Deliver LOCKED_BOOT_COMPLETED first 12229 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED) 12230 .setPackage(packageName); 12231 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED}; 12232 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions, 12233 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 12234 12235 // Deliver BOOT_COMPLETED only if user is unlocked 12236 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) { 12237 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName); 12238 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions, 12239 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 12240 } 12241 } catch (RemoteException e) { 12242 throw e.rethrowFromSystemServer(); 12243 } 12244 } 12245 12246 @Override 12247 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 12248 int userId) { 12249 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 12250 PackageSetting pkgSetting; 12251 final int uid = Binder.getCallingUid(); 12252 enforceCrossUserPermission(uid, userId, 12253 true /* requireFullPermission */, true /* checkShell */, 12254 "setApplicationHiddenSetting for user " + userId); 12255 12256 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 12257 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 12258 return false; 12259 } 12260 12261 long callingId = Binder.clearCallingIdentity(); 12262 try { 12263 boolean sendAdded = false; 12264 boolean sendRemoved = false; 12265 // writer 12266 synchronized (mPackages) { 12267 pkgSetting = mSettings.mPackages.get(packageName); 12268 if (pkgSetting == null) { 12269 return false; 12270 } 12271 // Do not allow "android" is being disabled 12272 if ("android".equals(packageName)) { 12273 Slog.w(TAG, "Cannot hide package: android"); 12274 return false; 12275 } 12276 // Only allow protected packages to hide themselves. 12277 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 12278 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 12279 Slog.w(TAG, "Not hiding protected package: " + packageName); 12280 return false; 12281 } 12282 12283 if (pkgSetting.getHidden(userId) != hidden) { 12284 pkgSetting.setHidden(hidden, userId); 12285 mSettings.writePackageRestrictionsLPr(userId); 12286 if (hidden) { 12287 sendRemoved = true; 12288 } else { 12289 sendAdded = true; 12290 } 12291 } 12292 } 12293 if (sendAdded) { 12294 sendPackageAddedForUser(packageName, pkgSetting, userId); 12295 return true; 12296 } 12297 if (sendRemoved) { 12298 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 12299 "hiding pkg"); 12300 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 12301 return true; 12302 } 12303 } finally { 12304 Binder.restoreCallingIdentity(callingId); 12305 } 12306 return false; 12307 } 12308 12309 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 12310 int userId) { 12311 final PackageRemovedInfo info = new PackageRemovedInfo(); 12312 info.removedPackage = packageName; 12313 info.removedUsers = new int[] {userId}; 12314 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 12315 info.sendPackageRemovedBroadcasts(true /*killApp*/); 12316 } 12317 12318 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 12319 if (pkgList.length > 0) { 12320 Bundle extras = new Bundle(1); 12321 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 12322 12323 sendPackageBroadcast( 12324 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 12325 : Intent.ACTION_PACKAGES_UNSUSPENDED, 12326 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 12327 new int[] {userId}); 12328 } 12329 } 12330 12331 /** 12332 * Returns true if application is not found or there was an error. Otherwise it returns 12333 * the hidden state of the package for the given user. 12334 */ 12335 @Override 12336 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 12337 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 12338 enforceCrossUserPermission(Binder.getCallingUid(), userId, 12339 true /* requireFullPermission */, false /* checkShell */, 12340 "getApplicationHidden for user " + userId); 12341 PackageSetting pkgSetting; 12342 long callingId = Binder.clearCallingIdentity(); 12343 try { 12344 // writer 12345 synchronized (mPackages) { 12346 pkgSetting = mSettings.mPackages.get(packageName); 12347 if (pkgSetting == null) { 12348 return true; 12349 } 12350 return pkgSetting.getHidden(userId); 12351 } 12352 } finally { 12353 Binder.restoreCallingIdentity(callingId); 12354 } 12355 } 12356 12357 /** 12358 * @hide 12359 */ 12360 @Override 12361 public int installExistingPackageAsUser(String packageName, int userId, int installReason) { 12362 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 12363 null); 12364 PackageSetting pkgSetting; 12365 final int uid = Binder.getCallingUid(); 12366 enforceCrossUserPermission(uid, userId, 12367 true /* requireFullPermission */, true /* checkShell */, 12368 "installExistingPackage for user " + userId); 12369 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 12370 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 12371 } 12372 12373 long callingId = Binder.clearCallingIdentity(); 12374 try { 12375 boolean installed = false; 12376 12377 // writer 12378 synchronized (mPackages) { 12379 pkgSetting = mSettings.mPackages.get(packageName); 12380 if (pkgSetting == null) { 12381 return PackageManager.INSTALL_FAILED_INVALID_URI; 12382 } 12383 if (!pkgSetting.getInstalled(userId)) { 12384 pkgSetting.setInstalled(true, userId); 12385 pkgSetting.setHidden(false, userId); 12386 pkgSetting.setInstallReason(installReason, userId); 12387 mSettings.writePackageRestrictionsLPr(userId); 12388 installed = true; 12389 } 12390 } 12391 12392 if (installed) { 12393 if (pkgSetting.pkg != null) { 12394 synchronized (mInstallLock) { 12395 // We don't need to freeze for a brand new install 12396 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 12397 } 12398 } 12399 sendPackageAddedForUser(packageName, pkgSetting, userId); 12400 } 12401 } finally { 12402 Binder.restoreCallingIdentity(callingId); 12403 } 12404 12405 return PackageManager.INSTALL_SUCCEEDED; 12406 } 12407 12408 boolean isUserRestricted(int userId, String restrictionKey) { 12409 Bundle restrictions = sUserManager.getUserRestrictions(userId); 12410 if (restrictions.getBoolean(restrictionKey, false)) { 12411 Log.w(TAG, "User is restricted: " + restrictionKey); 12412 return true; 12413 } 12414 return false; 12415 } 12416 12417 @Override 12418 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 12419 int userId) { 12420 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 12421 enforceCrossUserPermission(Binder.getCallingUid(), userId, 12422 true /* requireFullPermission */, true /* checkShell */, 12423 "setPackagesSuspended for user " + userId); 12424 12425 if (ArrayUtils.isEmpty(packageNames)) { 12426 return packageNames; 12427 } 12428 12429 // List of package names for whom the suspended state has changed. 12430 List<String> changedPackages = new ArrayList<>(packageNames.length); 12431 // List of package names for whom the suspended state is not set as requested in this 12432 // method. 12433 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 12434 long callingId = Binder.clearCallingIdentity(); 12435 try { 12436 for (int i = 0; i < packageNames.length; i++) { 12437 String packageName = packageNames[i]; 12438 boolean changed = false; 12439 final int appId; 12440 synchronized (mPackages) { 12441 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 12442 if (pkgSetting == null) { 12443 Slog.w(TAG, "Could not find package setting for package \"" + packageName 12444 + "\". Skipping suspending/un-suspending."); 12445 unactionedPackages.add(packageName); 12446 continue; 12447 } 12448 appId = pkgSetting.appId; 12449 if (pkgSetting.getSuspended(userId) != suspended) { 12450 if (!canSuspendPackageForUserLocked(packageName, userId)) { 12451 unactionedPackages.add(packageName); 12452 continue; 12453 } 12454 pkgSetting.setSuspended(suspended, userId); 12455 mSettings.writePackageRestrictionsLPr(userId); 12456 changed = true; 12457 changedPackages.add(packageName); 12458 } 12459 } 12460 12461 if (changed && suspended) { 12462 killApplication(packageName, UserHandle.getUid(userId, appId), 12463 "suspending package"); 12464 } 12465 } 12466 } finally { 12467 Binder.restoreCallingIdentity(callingId); 12468 } 12469 12470 if (!changedPackages.isEmpty()) { 12471 sendPackagesSuspendedForUser(changedPackages.toArray( 12472 new String[changedPackages.size()]), userId, suspended); 12473 } 12474 12475 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 12476 } 12477 12478 @Override 12479 public boolean isPackageSuspendedForUser(String packageName, int userId) { 12480 enforceCrossUserPermission(Binder.getCallingUid(), userId, 12481 true /* requireFullPermission */, false /* checkShell */, 12482 "isPackageSuspendedForUser for user " + userId); 12483 synchronized (mPackages) { 12484 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 12485 if (pkgSetting == null) { 12486 throw new IllegalArgumentException("Unknown target package: " + packageName); 12487 } 12488 return pkgSetting.getSuspended(userId); 12489 } 12490 } 12491 12492 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 12493 if (isPackageDeviceAdmin(packageName, userId)) { 12494 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12495 + "\": has an active device admin"); 12496 return false; 12497 } 12498 12499 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 12500 if (packageName.equals(activeLauncherPackageName)) { 12501 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12502 + "\": contains the active launcher"); 12503 return false; 12504 } 12505 12506 if (packageName.equals(mRequiredInstallerPackage)) { 12507 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12508 + "\": required for package installation"); 12509 return false; 12510 } 12511 12512 if (packageName.equals(mRequiredUninstallerPackage)) { 12513 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12514 + "\": required for package uninstallation"); 12515 return false; 12516 } 12517 12518 if (packageName.equals(mRequiredVerifierPackage)) { 12519 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12520 + "\": required for package verification"); 12521 return false; 12522 } 12523 12524 if (packageName.equals(getDefaultDialerPackageName(userId))) { 12525 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12526 + "\": is the default dialer"); 12527 return false; 12528 } 12529 12530 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 12531 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12532 + "\": protected package"); 12533 return false; 12534 } 12535 12536 return true; 12537 } 12538 12539 private String getActiveLauncherPackageName(int userId) { 12540 Intent intent = new Intent(Intent.ACTION_MAIN); 12541 intent.addCategory(Intent.CATEGORY_HOME); 12542 ResolveInfo resolveInfo = resolveIntent( 12543 intent, 12544 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 12545 PackageManager.MATCH_DEFAULT_ONLY, 12546 userId); 12547 12548 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 12549 } 12550 12551 private String getDefaultDialerPackageName(int userId) { 12552 synchronized (mPackages) { 12553 return mSettings.getDefaultDialerPackageNameLPw(userId); 12554 } 12555 } 12556 12557 @Override 12558 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 12559 mContext.enforceCallingOrSelfPermission( 12560 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12561 "Only package verification agents can verify applications"); 12562 12563 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12564 final PackageVerificationResponse response = new PackageVerificationResponse( 12565 verificationCode, Binder.getCallingUid()); 12566 msg.arg1 = id; 12567 msg.obj = response; 12568 mHandler.sendMessage(msg); 12569 } 12570 12571 @Override 12572 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 12573 long millisecondsToDelay) { 12574 mContext.enforceCallingOrSelfPermission( 12575 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12576 "Only package verification agents can extend verification timeouts"); 12577 12578 final PackageVerificationState state = mPendingVerification.get(id); 12579 final PackageVerificationResponse response = new PackageVerificationResponse( 12580 verificationCodeAtTimeout, Binder.getCallingUid()); 12581 12582 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 12583 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 12584 } 12585 if (millisecondsToDelay < 0) { 12586 millisecondsToDelay = 0; 12587 } 12588 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 12589 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 12590 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 12591 } 12592 12593 if ((state != null) && !state.timeoutExtended()) { 12594 state.extendTimeout(); 12595 12596 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12597 msg.arg1 = id; 12598 msg.obj = response; 12599 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 12600 } 12601 } 12602 12603 private void broadcastPackageVerified(int verificationId, Uri packageUri, 12604 int verificationCode, UserHandle user) { 12605 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 12606 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 12607 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 12608 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 12609 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 12610 12611 mContext.sendBroadcastAsUser(intent, user, 12612 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 12613 } 12614 12615 private ComponentName matchComponentForVerifier(String packageName, 12616 List<ResolveInfo> receivers) { 12617 ActivityInfo targetReceiver = null; 12618 12619 final int NR = receivers.size(); 12620 for (int i = 0; i < NR; i++) { 12621 final ResolveInfo info = receivers.get(i); 12622 if (info.activityInfo == null) { 12623 continue; 12624 } 12625 12626 if (packageName.equals(info.activityInfo.packageName)) { 12627 targetReceiver = info.activityInfo; 12628 break; 12629 } 12630 } 12631 12632 if (targetReceiver == null) { 12633 return null; 12634 } 12635 12636 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 12637 } 12638 12639 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 12640 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 12641 if (pkgInfo.verifiers.length == 0) { 12642 return null; 12643 } 12644 12645 final int N = pkgInfo.verifiers.length; 12646 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 12647 for (int i = 0; i < N; i++) { 12648 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 12649 12650 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 12651 receivers); 12652 if (comp == null) { 12653 continue; 12654 } 12655 12656 final int verifierUid = getUidForVerifier(verifierInfo); 12657 if (verifierUid == -1) { 12658 continue; 12659 } 12660 12661 if (DEBUG_VERIFY) { 12662 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 12663 + " with the correct signature"); 12664 } 12665 sufficientVerifiers.add(comp); 12666 verificationState.addSufficientVerifier(verifierUid); 12667 } 12668 12669 return sufficientVerifiers; 12670 } 12671 12672 private int getUidForVerifier(VerifierInfo verifierInfo) { 12673 synchronized (mPackages) { 12674 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 12675 if (pkg == null) { 12676 return -1; 12677 } else if (pkg.mSignatures.length != 1) { 12678 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12679 + " has more than one signature; ignoring"); 12680 return -1; 12681 } 12682 12683 /* 12684 * If the public key of the package's signature does not match 12685 * our expected public key, then this is a different package and 12686 * we should skip. 12687 */ 12688 12689 final byte[] expectedPublicKey; 12690 try { 12691 final Signature verifierSig = pkg.mSignatures[0]; 12692 final PublicKey publicKey = verifierSig.getPublicKey(); 12693 expectedPublicKey = publicKey.getEncoded(); 12694 } catch (CertificateException e) { 12695 return -1; 12696 } 12697 12698 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 12699 12700 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 12701 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12702 + " does not have the expected public key; ignoring"); 12703 return -1; 12704 } 12705 12706 return pkg.applicationInfo.uid; 12707 } 12708 } 12709 12710 @Override 12711 public void finishPackageInstall(int token, boolean didLaunch) { 12712 enforceSystemOrRoot("Only the system is allowed to finish installs"); 12713 12714 if (DEBUG_INSTALL) { 12715 Slog.v(TAG, "BM finishing package install for " + token); 12716 } 12717 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12718 12719 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 12720 mHandler.sendMessage(msg); 12721 } 12722 12723 /** 12724 * Get the verification agent timeout. 12725 * 12726 * @return verification timeout in milliseconds 12727 */ 12728 private long getVerificationTimeout() { 12729 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 12730 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 12731 DEFAULT_VERIFICATION_TIMEOUT); 12732 } 12733 12734 /** 12735 * Get the default verification agent response code. 12736 * 12737 * @return default verification response code 12738 */ 12739 private int getDefaultVerificationResponse() { 12740 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12741 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 12742 DEFAULT_VERIFICATION_RESPONSE); 12743 } 12744 12745 /** 12746 * Check whether or not package verification has been enabled. 12747 * 12748 * @return true if verification should be performed 12749 */ 12750 private boolean isVerificationEnabled(int userId, int installFlags) { 12751 if (!DEFAULT_VERIFY_ENABLE) { 12752 return false; 12753 } 12754 // Ephemeral apps don't get the full verification treatment 12755 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 12756 if (DEBUG_EPHEMERAL) { 12757 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 12758 } 12759 return false; 12760 } 12761 12762 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 12763 12764 // Check if installing from ADB 12765 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 12766 // Do not run verification in a test harness environment 12767 if (ActivityManager.isRunningInTestHarness()) { 12768 return false; 12769 } 12770 if (ensureVerifyAppsEnabled) { 12771 return true; 12772 } 12773 // Check if the developer does not want package verification for ADB installs 12774 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12775 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 12776 return false; 12777 } 12778 } 12779 12780 if (ensureVerifyAppsEnabled) { 12781 return true; 12782 } 12783 12784 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12785 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 12786 } 12787 12788 @Override 12789 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 12790 throws RemoteException { 12791 mContext.enforceCallingOrSelfPermission( 12792 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 12793 "Only intentfilter verification agents can verify applications"); 12794 12795 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 12796 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 12797 Binder.getCallingUid(), verificationCode, failedDomains); 12798 msg.arg1 = id; 12799 msg.obj = response; 12800 mHandler.sendMessage(msg); 12801 } 12802 12803 @Override 12804 public int getIntentVerificationStatus(String packageName, int userId) { 12805 synchronized (mPackages) { 12806 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 12807 } 12808 } 12809 12810 @Override 12811 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 12812 mContext.enforceCallingOrSelfPermission( 12813 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12814 12815 boolean result = false; 12816 synchronized (mPackages) { 12817 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 12818 } 12819 if (result) { 12820 scheduleWritePackageRestrictionsLocked(userId); 12821 } 12822 return result; 12823 } 12824 12825 @Override 12826 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 12827 String packageName) { 12828 synchronized (mPackages) { 12829 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 12830 } 12831 } 12832 12833 @Override 12834 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 12835 if (TextUtils.isEmpty(packageName)) { 12836 return ParceledListSlice.emptyList(); 12837 } 12838 synchronized (mPackages) { 12839 PackageParser.Package pkg = mPackages.get(packageName); 12840 if (pkg == null || pkg.activities == null) { 12841 return ParceledListSlice.emptyList(); 12842 } 12843 final int count = pkg.activities.size(); 12844 ArrayList<IntentFilter> result = new ArrayList<>(); 12845 for (int n=0; n<count; n++) { 12846 PackageParser.Activity activity = pkg.activities.get(n); 12847 if (activity.intents != null && activity.intents.size() > 0) { 12848 result.addAll(activity.intents); 12849 } 12850 } 12851 return new ParceledListSlice<>(result); 12852 } 12853 } 12854 12855 @Override 12856 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 12857 mContext.enforceCallingOrSelfPermission( 12858 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12859 12860 synchronized (mPackages) { 12861 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 12862 if (packageName != null) { 12863 result |= updateIntentVerificationStatus(packageName, 12864 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 12865 userId); 12866 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 12867 packageName, userId); 12868 } 12869 return result; 12870 } 12871 } 12872 12873 @Override 12874 public String getDefaultBrowserPackageName(int userId) { 12875 synchronized (mPackages) { 12876 return mSettings.getDefaultBrowserPackageNameLPw(userId); 12877 } 12878 } 12879 12880 /** 12881 * Get the "allow unknown sources" setting. 12882 * 12883 * @return the current "allow unknown sources" setting 12884 */ 12885 private int getUnknownSourcesSettings() { 12886 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 12887 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 12888 -1); 12889 } 12890 12891 @Override 12892 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 12893 final int uid = Binder.getCallingUid(); 12894 // writer 12895 synchronized (mPackages) { 12896 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 12897 if (targetPackageSetting == null) { 12898 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 12899 } 12900 12901 PackageSetting installerPackageSetting; 12902 if (installerPackageName != null) { 12903 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 12904 if (installerPackageSetting == null) { 12905 throw new IllegalArgumentException("Unknown installer package: " 12906 + installerPackageName); 12907 } 12908 } else { 12909 installerPackageSetting = null; 12910 } 12911 12912 Signature[] callerSignature; 12913 Object obj = mSettings.getUserIdLPr(uid); 12914 if (obj != null) { 12915 if (obj instanceof SharedUserSetting) { 12916 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 12917 } else if (obj instanceof PackageSetting) { 12918 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 12919 } else { 12920 throw new SecurityException("Bad object " + obj + " for uid " + uid); 12921 } 12922 } else { 12923 throw new SecurityException("Unknown calling UID: " + uid); 12924 } 12925 12926 // Verify: can't set installerPackageName to a package that is 12927 // not signed with the same cert as the caller. 12928 if (installerPackageSetting != null) { 12929 if (compareSignatures(callerSignature, 12930 installerPackageSetting.signatures.mSignatures) 12931 != PackageManager.SIGNATURE_MATCH) { 12932 throw new SecurityException( 12933 "Caller does not have same cert as new installer package " 12934 + installerPackageName); 12935 } 12936 } 12937 12938 // Verify: if target already has an installer package, it must 12939 // be signed with the same cert as the caller. 12940 if (targetPackageSetting.installerPackageName != null) { 12941 PackageSetting setting = mSettings.mPackages.get( 12942 targetPackageSetting.installerPackageName); 12943 // If the currently set package isn't valid, then it's always 12944 // okay to change it. 12945 if (setting != null) { 12946 if (compareSignatures(callerSignature, 12947 setting.signatures.mSignatures) 12948 != PackageManager.SIGNATURE_MATCH) { 12949 throw new SecurityException( 12950 "Caller does not have same cert as old installer package " 12951 + targetPackageSetting.installerPackageName); 12952 } 12953 } 12954 } 12955 12956 // Okay! 12957 targetPackageSetting.installerPackageName = installerPackageName; 12958 if (installerPackageName != null) { 12959 mSettings.mInstallerPackages.add(installerPackageName); 12960 } 12961 scheduleWriteSettingsLocked(); 12962 } 12963 } 12964 12965 @Override 12966 public void setApplicationCategoryHint(String packageName, int categoryHint, 12967 String callerPackageName) { 12968 mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), 12969 callerPackageName); 12970 synchronized (mPackages) { 12971 PackageSetting ps = mSettings.mPackages.get(packageName); 12972 if (ps == null) { 12973 throw new IllegalArgumentException("Unknown target package " + packageName); 12974 } 12975 12976 if (!Objects.equals(callerPackageName, ps.installerPackageName)) { 12977 throw new IllegalArgumentException("Calling package " + callerPackageName 12978 + " is not installer for " + packageName); 12979 } 12980 12981 ps.categoryHint = categoryHint; 12982 scheduleWriteSettingsLocked(); 12983 } 12984 } 12985 12986 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 12987 // Queue up an async operation since the package installation may take a little while. 12988 mHandler.post(new Runnable() { 12989 public void run() { 12990 mHandler.removeCallbacks(this); 12991 // Result object to be returned 12992 PackageInstalledInfo res = new PackageInstalledInfo(); 12993 res.setReturnCode(currentStatus); 12994 res.uid = -1; 12995 res.pkg = null; 12996 res.removedInfo = null; 12997 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12998 args.doPreInstall(res.returnCode); 12999 synchronized (mInstallLock) { 13000 installPackageTracedLI(args, res); 13001 } 13002 args.doPostInstall(res.returnCode, res.uid); 13003 } 13004 13005 // A restore should be performed at this point if (a) the install 13006 // succeeded, (b) the operation is not an update, and (c) the new 13007 // package has not opted out of backup participation. 13008 final boolean update = res.removedInfo != null 13009 && res.removedInfo.removedPackage != null; 13010 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 13011 boolean doRestore = !update 13012 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 13013 13014 // Set up the post-install work request bookkeeping. This will be used 13015 // and cleaned up by the post-install event handling regardless of whether 13016 // there's a restore pass performed. Token values are >= 1. 13017 int token; 13018 if (mNextInstallToken < 0) mNextInstallToken = 1; 13019 token = mNextInstallToken++; 13020 13021 PostInstallData data = new PostInstallData(args, res); 13022 mRunningInstalls.put(token, data); 13023 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 13024 13025 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 13026 // Pass responsibility to the Backup Manager. It will perform a 13027 // restore if appropriate, then pass responsibility back to the 13028 // Package Manager to run the post-install observer callbacks 13029 // and broadcasts. 13030 IBackupManager bm = IBackupManager.Stub.asInterface( 13031 ServiceManager.getService(Context.BACKUP_SERVICE)); 13032 if (bm != null) { 13033 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 13034 + " to BM for possible restore"); 13035 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 13036 try { 13037 // TODO: http://b/22388012 13038 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 13039 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 13040 } else { 13041 doRestore = false; 13042 } 13043 } catch (RemoteException e) { 13044 // can't happen; the backup manager is local 13045 } catch (Exception e) { 13046 Slog.e(TAG, "Exception trying to enqueue restore", e); 13047 doRestore = false; 13048 } 13049 } else { 13050 Slog.e(TAG, "Backup Manager not found!"); 13051 doRestore = false; 13052 } 13053 } 13054 13055 if (!doRestore) { 13056 // No restore possible, or the Backup Manager was mysteriously not 13057 // available -- just fire the post-install work request directly. 13058 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 13059 13060 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 13061 13062 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 13063 mHandler.sendMessage(msg); 13064 } 13065 } 13066 }); 13067 } 13068 13069 /** 13070 * Callback from PackageSettings whenever an app is first transitioned out of the 13071 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 13072 * the app was "launched" for a restoreAtInstall operation. Therefore we check 13073 * here whether the app is the target of an ongoing install, and only send the 13074 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 13075 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 13076 * handling. 13077 */ 13078 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 13079 // Serialize this with the rest of the install-process message chain. In the 13080 // restore-at-install case, this Runnable will necessarily run before the 13081 // POST_INSTALL message is processed, so the contents of mRunningInstalls 13082 // are coherent. In the non-restore case, the app has already completed install 13083 // and been launched through some other means, so it is not in a problematic 13084 // state for observers to see the FIRST_LAUNCH signal. 13085 mHandler.post(new Runnable() { 13086 @Override 13087 public void run() { 13088 for (int i = 0; i < mRunningInstalls.size(); i++) { 13089 final PostInstallData data = mRunningInstalls.valueAt(i); 13090 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13091 continue; 13092 } 13093 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 13094 // right package; but is it for the right user? 13095 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 13096 if (userId == data.res.newUsers[uIndex]) { 13097 if (DEBUG_BACKUP) { 13098 Slog.i(TAG, "Package " + pkgName 13099 + " being restored so deferring FIRST_LAUNCH"); 13100 } 13101 return; 13102 } 13103 } 13104 } 13105 } 13106 // didn't find it, so not being restored 13107 if (DEBUG_BACKUP) { 13108 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 13109 } 13110 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 13111 } 13112 }); 13113 } 13114 13115 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 13116 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 13117 installerPkg, null, userIds); 13118 } 13119 13120 private abstract class HandlerParams { 13121 private static final int MAX_RETRIES = 4; 13122 13123 /** 13124 * Number of times startCopy() has been attempted and had a non-fatal 13125 * error. 13126 */ 13127 private int mRetries = 0; 13128 13129 /** User handle for the user requesting the information or installation. */ 13130 private final UserHandle mUser; 13131 String traceMethod; 13132 int traceCookie; 13133 13134 HandlerParams(UserHandle user) { 13135 mUser = user; 13136 } 13137 13138 UserHandle getUser() { 13139 return mUser; 13140 } 13141 13142 HandlerParams setTraceMethod(String traceMethod) { 13143 this.traceMethod = traceMethod; 13144 return this; 13145 } 13146 13147 HandlerParams setTraceCookie(int traceCookie) { 13148 this.traceCookie = traceCookie; 13149 return this; 13150 } 13151 13152 final boolean startCopy() { 13153 boolean res; 13154 try { 13155 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 13156 13157 if (++mRetries > MAX_RETRIES) { 13158 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 13159 mHandler.sendEmptyMessage(MCS_GIVE_UP); 13160 handleServiceError(); 13161 return false; 13162 } else { 13163 handleStartCopy(); 13164 res = true; 13165 } 13166 } catch (RemoteException e) { 13167 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 13168 mHandler.sendEmptyMessage(MCS_RECONNECT); 13169 res = false; 13170 } 13171 handleReturnCode(); 13172 return res; 13173 } 13174 13175 final void serviceError() { 13176 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 13177 handleServiceError(); 13178 handleReturnCode(); 13179 } 13180 13181 abstract void handleStartCopy() throws RemoteException; 13182 abstract void handleServiceError(); 13183 abstract void handleReturnCode(); 13184 } 13185 13186 class MeasureParams extends HandlerParams { 13187 private final PackageStats mStats; 13188 private boolean mSuccess; 13189 13190 private final IPackageStatsObserver mObserver; 13191 13192 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 13193 super(new UserHandle(stats.userHandle)); 13194 mObserver = observer; 13195 mStats = stats; 13196 } 13197 13198 @Override 13199 public String toString() { 13200 return "MeasureParams{" 13201 + Integer.toHexString(System.identityHashCode(this)) 13202 + " " + mStats.packageName + "}"; 13203 } 13204 13205 @Override 13206 void handleStartCopy() throws RemoteException { 13207 synchronized (mInstallLock) { 13208 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 13209 } 13210 13211 if (mSuccess) { 13212 boolean mounted = false; 13213 try { 13214 final String status = Environment.getExternalStorageState(); 13215 mounted = (Environment.MEDIA_MOUNTED.equals(status) 13216 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 13217 } catch (Exception e) { 13218 } 13219 13220 if (mounted) { 13221 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 13222 13223 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 13224 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 13225 13226 mStats.externalDataSize = calculateDirectorySize(mContainerService, 13227 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 13228 13229 // Always subtract cache size, since it's a subdirectory 13230 mStats.externalDataSize -= mStats.externalCacheSize; 13231 13232 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 13233 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 13234 13235 mStats.externalObbSize = calculateDirectorySize(mContainerService, 13236 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 13237 } 13238 } 13239 } 13240 13241 @Override 13242 void handleReturnCode() { 13243 if (mObserver != null) { 13244 try { 13245 mObserver.onGetStatsCompleted(mStats, mSuccess); 13246 } catch (RemoteException e) { 13247 Slog.i(TAG, "Observer no longer exists."); 13248 } 13249 } 13250 } 13251 13252 @Override 13253 void handleServiceError() { 13254 Slog.e(TAG, "Could not measure application " + mStats.packageName 13255 + " external storage"); 13256 } 13257 } 13258 13259 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 13260 throws RemoteException { 13261 long result = 0; 13262 for (File path : paths) { 13263 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 13264 } 13265 return result; 13266 } 13267 13268 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 13269 for (File path : paths) { 13270 try { 13271 mcs.clearDirectory(path.getAbsolutePath()); 13272 } catch (RemoteException e) { 13273 } 13274 } 13275 } 13276 13277 static class OriginInfo { 13278 /** 13279 * Location where install is coming from, before it has been 13280 * copied/renamed into place. This could be a single monolithic APK 13281 * file, or a cluster directory. This location may be untrusted. 13282 */ 13283 final File file; 13284 final String cid; 13285 13286 /** 13287 * Flag indicating that {@link #file} or {@link #cid} has already been 13288 * staged, meaning downstream users don't need to defensively copy the 13289 * contents. 13290 */ 13291 final boolean staged; 13292 13293 /** 13294 * Flag indicating that {@link #file} or {@link #cid} is an already 13295 * installed app that is being moved. 13296 */ 13297 final boolean existing; 13298 13299 final String resolvedPath; 13300 final File resolvedFile; 13301 13302 static OriginInfo fromNothing() { 13303 return new OriginInfo(null, null, false, false); 13304 } 13305 13306 static OriginInfo fromUntrustedFile(File file) { 13307 return new OriginInfo(file, null, false, false); 13308 } 13309 13310 static OriginInfo fromExistingFile(File file) { 13311 return new OriginInfo(file, null, false, true); 13312 } 13313 13314 static OriginInfo fromStagedFile(File file) { 13315 return new OriginInfo(file, null, true, false); 13316 } 13317 13318 static OriginInfo fromStagedContainer(String cid) { 13319 return new OriginInfo(null, cid, true, false); 13320 } 13321 13322 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 13323 this.file = file; 13324 this.cid = cid; 13325 this.staged = staged; 13326 this.existing = existing; 13327 13328 if (cid != null) { 13329 resolvedPath = PackageHelper.getSdDir(cid); 13330 resolvedFile = new File(resolvedPath); 13331 } else if (file != null) { 13332 resolvedPath = file.getAbsolutePath(); 13333 resolvedFile = file; 13334 } else { 13335 resolvedPath = null; 13336 resolvedFile = null; 13337 } 13338 } 13339 } 13340 13341 static class MoveInfo { 13342 final int moveId; 13343 final String fromUuid; 13344 final String toUuid; 13345 final String packageName; 13346 final String dataAppName; 13347 final int appId; 13348 final String seinfo; 13349 final int targetSdkVersion; 13350 13351 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 13352 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 13353 this.moveId = moveId; 13354 this.fromUuid = fromUuid; 13355 this.toUuid = toUuid; 13356 this.packageName = packageName; 13357 this.dataAppName = dataAppName; 13358 this.appId = appId; 13359 this.seinfo = seinfo; 13360 this.targetSdkVersion = targetSdkVersion; 13361 } 13362 } 13363 13364 static class VerificationInfo { 13365 /** A constant used to indicate that a uid value is not present. */ 13366 public static final int NO_UID = -1; 13367 13368 /** URI referencing where the package was downloaded from. */ 13369 final Uri originatingUri; 13370 13371 /** HTTP referrer URI associated with the originatingURI. */ 13372 final Uri referrer; 13373 13374 /** UID of the application that the install request originated from. */ 13375 final int originatingUid; 13376 13377 /** UID of application requesting the install */ 13378 final int installerUid; 13379 13380 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 13381 this.originatingUri = originatingUri; 13382 this.referrer = referrer; 13383 this.originatingUid = originatingUid; 13384 this.installerUid = installerUid; 13385 } 13386 } 13387 13388 class InstallParams extends HandlerParams { 13389 final OriginInfo origin; 13390 final MoveInfo move; 13391 final IPackageInstallObserver2 observer; 13392 int installFlags; 13393 final String installerPackageName; 13394 final String volumeUuid; 13395 private InstallArgs mArgs; 13396 private int mRet; 13397 final String packageAbiOverride; 13398 final String[] grantedRuntimePermissions; 13399 final VerificationInfo verificationInfo; 13400 final Certificate[][] certificates; 13401 final int installReason; 13402 13403 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 13404 int installFlags, String installerPackageName, String volumeUuid, 13405 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 13406 String[] grantedPermissions, Certificate[][] certificates, int installReason) { 13407 super(user); 13408 this.origin = origin; 13409 this.move = move; 13410 this.observer = observer; 13411 this.installFlags = installFlags; 13412 this.installerPackageName = installerPackageName; 13413 this.volumeUuid = volumeUuid; 13414 this.verificationInfo = verificationInfo; 13415 this.packageAbiOverride = packageAbiOverride; 13416 this.grantedRuntimePermissions = grantedPermissions; 13417 this.certificates = certificates; 13418 this.installReason = installReason; 13419 } 13420 13421 @Override 13422 public String toString() { 13423 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 13424 + " file=" + origin.file + " cid=" + origin.cid + "}"; 13425 } 13426 13427 private int installLocationPolicy(PackageInfoLite pkgLite) { 13428 String packageName = pkgLite.packageName; 13429 int installLocation = pkgLite.installLocation; 13430 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13431 // reader 13432 synchronized (mPackages) { 13433 // Currently installed package which the new package is attempting to replace or 13434 // null if no such package is installed. 13435 PackageParser.Package installedPkg = mPackages.get(packageName); 13436 // Package which currently owns the data which the new package will own if installed. 13437 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 13438 // will be null whereas dataOwnerPkg will contain information about the package 13439 // which was uninstalled while keeping its data. 13440 PackageParser.Package dataOwnerPkg = installedPkg; 13441 if (dataOwnerPkg == null) { 13442 PackageSetting ps = mSettings.mPackages.get(packageName); 13443 if (ps != null) { 13444 dataOwnerPkg = ps.pkg; 13445 } 13446 } 13447 13448 if (dataOwnerPkg != null) { 13449 // If installed, the package will get access to data left on the device by its 13450 // predecessor. As a security measure, this is permited only if this is not a 13451 // version downgrade or if the predecessor package is marked as debuggable and 13452 // a downgrade is explicitly requested. 13453 // 13454 // On debuggable platform builds, downgrades are permitted even for 13455 // non-debuggable packages to make testing easier. Debuggable platform builds do 13456 // not offer security guarantees and thus it's OK to disable some security 13457 // mechanisms to make debugging/testing easier on those builds. However, even on 13458 // debuggable builds downgrades of packages are permitted only if requested via 13459 // installFlags. This is because we aim to keep the behavior of debuggable 13460 // platform builds as close as possible to the behavior of non-debuggable 13461 // platform builds. 13462 final boolean downgradeRequested = 13463 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 13464 final boolean packageDebuggable = 13465 (dataOwnerPkg.applicationInfo.flags 13466 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 13467 final boolean downgradePermitted = 13468 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 13469 if (!downgradePermitted) { 13470 try { 13471 checkDowngrade(dataOwnerPkg, pkgLite); 13472 } catch (PackageManagerException e) { 13473 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 13474 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 13475 } 13476 } 13477 } 13478 13479 if (installedPkg != null) { 13480 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 13481 // Check for updated system application. 13482 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 13483 if (onSd) { 13484 Slog.w(TAG, "Cannot install update to system app on sdcard"); 13485 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 13486 } 13487 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 13488 } else { 13489 if (onSd) { 13490 // Install flag overrides everything. 13491 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 13492 } 13493 // If current upgrade specifies particular preference 13494 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 13495 // Application explicitly specified internal. 13496 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 13497 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 13498 // App explictly prefers external. Let policy decide 13499 } else { 13500 // Prefer previous location 13501 if (isExternal(installedPkg)) { 13502 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 13503 } 13504 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 13505 } 13506 } 13507 } else { 13508 // Invalid install. Return error code 13509 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 13510 } 13511 } 13512 } 13513 // All the special cases have been taken care of. 13514 // Return result based on recommended install location. 13515 if (onSd) { 13516 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 13517 } 13518 return pkgLite.recommendedInstallLocation; 13519 } 13520 13521 /* 13522 * Invoke remote method to get package information and install 13523 * location values. Override install location based on default 13524 * policy if needed and then create install arguments based 13525 * on the install location. 13526 */ 13527 public void handleStartCopy() throws RemoteException { 13528 int ret = PackageManager.INSTALL_SUCCEEDED; 13529 13530 // If we're already staged, we've firmly committed to an install location 13531 if (origin.staged) { 13532 if (origin.file != null) { 13533 installFlags |= PackageManager.INSTALL_INTERNAL; 13534 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 13535 } else if (origin.cid != null) { 13536 installFlags |= PackageManager.INSTALL_EXTERNAL; 13537 installFlags &= ~PackageManager.INSTALL_INTERNAL; 13538 } else { 13539 throw new IllegalStateException("Invalid stage location"); 13540 } 13541 } 13542 13543 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13544 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 13545 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13546 PackageInfoLite pkgLite = null; 13547 13548 if (onInt && onSd) { 13549 // Check if both bits are set. 13550 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 13551 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13552 } else if (onSd && ephemeral) { 13553 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 13554 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13555 } else { 13556 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 13557 packageAbiOverride); 13558 13559 if (DEBUG_EPHEMERAL && ephemeral) { 13560 Slog.v(TAG, "pkgLite for install: " + pkgLite); 13561 } 13562 13563 /* 13564 * If we have too little free space, try to free cache 13565 * before giving up. 13566 */ 13567 if (!origin.staged && pkgLite.recommendedInstallLocation 13568 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 13569 // TODO: focus freeing disk space on the target device 13570 final StorageManager storage = StorageManager.from(mContext); 13571 final long lowThreshold = storage.getStorageLowBytes( 13572 Environment.getDataDirectory()); 13573 13574 final long sizeBytes = mContainerService.calculateInstalledSize( 13575 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 13576 13577 try { 13578 mInstaller.freeCache(null, sizeBytes + lowThreshold); 13579 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 13580 installFlags, packageAbiOverride); 13581 } catch (InstallerException e) { 13582 Slog.w(TAG, "Failed to free cache", e); 13583 } 13584 13585 /* 13586 * The cache free must have deleted the file we 13587 * downloaded to install. 13588 * 13589 * TODO: fix the "freeCache" call to not delete 13590 * the file we care about. 13591 */ 13592 if (pkgLite.recommendedInstallLocation 13593 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13594 pkgLite.recommendedInstallLocation 13595 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 13596 } 13597 } 13598 } 13599 13600 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13601 int loc = pkgLite.recommendedInstallLocation; 13602 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 13603 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13604 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 13605 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 13606 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 13607 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13608 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 13609 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 13610 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13611 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 13612 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 13613 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 13614 } else { 13615 // Override with defaults if needed. 13616 loc = installLocationPolicy(pkgLite); 13617 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 13618 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 13619 } else if (!onSd && !onInt) { 13620 // Override install location with flags 13621 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 13622 // Set the flag to install on external media. 13623 installFlags |= PackageManager.INSTALL_EXTERNAL; 13624 installFlags &= ~PackageManager.INSTALL_INTERNAL; 13625 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 13626 if (DEBUG_EPHEMERAL) { 13627 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 13628 } 13629 installFlags |= PackageManager.INSTALL_EPHEMERAL; 13630 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 13631 |PackageManager.INSTALL_INTERNAL); 13632 } else { 13633 // Make sure the flag for installing on external 13634 // media is unset 13635 installFlags |= PackageManager.INSTALL_INTERNAL; 13636 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 13637 } 13638 } 13639 } 13640 } 13641 13642 final InstallArgs args = createInstallArgs(this); 13643 mArgs = args; 13644 13645 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13646 // TODO: http://b/22976637 13647 // Apps installed for "all" users use the device owner to verify the app 13648 UserHandle verifierUser = getUser(); 13649 if (verifierUser == UserHandle.ALL) { 13650 verifierUser = UserHandle.SYSTEM; 13651 } 13652 13653 /* 13654 * Determine if we have any installed package verifiers. If we 13655 * do, then we'll defer to them to verify the packages. 13656 */ 13657 final int requiredUid = mRequiredVerifierPackage == null ? -1 13658 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 13659 verifierUser.getIdentifier()); 13660 if (!origin.existing && requiredUid != -1 13661 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 13662 final Intent verification = new Intent( 13663 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 13664 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13665 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 13666 PACKAGE_MIME_TYPE); 13667 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 13668 13669 // Query all live verifiers based on current user state 13670 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 13671 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 13672 13673 if (DEBUG_VERIFY) { 13674 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 13675 + verification.toString() + " with " + pkgLite.verifiers.length 13676 + " optional verifiers"); 13677 } 13678 13679 final int verificationId = mPendingVerificationToken++; 13680 13681 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 13682 13683 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 13684 installerPackageName); 13685 13686 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 13687 installFlags); 13688 13689 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 13690 pkgLite.packageName); 13691 13692 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 13693 pkgLite.versionCode); 13694 13695 if (verificationInfo != null) { 13696 if (verificationInfo.originatingUri != null) { 13697 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 13698 verificationInfo.originatingUri); 13699 } 13700 if (verificationInfo.referrer != null) { 13701 verification.putExtra(Intent.EXTRA_REFERRER, 13702 verificationInfo.referrer); 13703 } 13704 if (verificationInfo.originatingUid >= 0) { 13705 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 13706 verificationInfo.originatingUid); 13707 } 13708 if (verificationInfo.installerUid >= 0) { 13709 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 13710 verificationInfo.installerUid); 13711 } 13712 } 13713 13714 final PackageVerificationState verificationState = new PackageVerificationState( 13715 requiredUid, args); 13716 13717 mPendingVerification.append(verificationId, verificationState); 13718 13719 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 13720 receivers, verificationState); 13721 13722 /* 13723 * If any sufficient verifiers were listed in the package 13724 * manifest, attempt to ask them. 13725 */ 13726 if (sufficientVerifiers != null) { 13727 final int N = sufficientVerifiers.size(); 13728 if (N == 0) { 13729 Slog.i(TAG, "Additional verifiers required, but none installed."); 13730 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 13731 } else { 13732 for (int i = 0; i < N; i++) { 13733 final ComponentName verifierComponent = sufficientVerifiers.get(i); 13734 13735 final Intent sufficientIntent = new Intent(verification); 13736 sufficientIntent.setComponent(verifierComponent); 13737 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 13738 } 13739 } 13740 } 13741 13742 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 13743 mRequiredVerifierPackage, receivers); 13744 if (ret == PackageManager.INSTALL_SUCCEEDED 13745 && mRequiredVerifierPackage != null) { 13746 Trace.asyncTraceBegin( 13747 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 13748 /* 13749 * Send the intent to the required verification agent, 13750 * but only start the verification timeout after the 13751 * target BroadcastReceivers have run. 13752 */ 13753 verification.setComponent(requiredVerifierComponent); 13754 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 13755 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13756 new BroadcastReceiver() { 13757 @Override 13758 public void onReceive(Context context, Intent intent) { 13759 final Message msg = mHandler 13760 .obtainMessage(CHECK_PENDING_VERIFICATION); 13761 msg.arg1 = verificationId; 13762 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 13763 } 13764 }, null, 0, null, null); 13765 13766 /* 13767 * We don't want the copy to proceed until verification 13768 * succeeds, so null out this field. 13769 */ 13770 mArgs = null; 13771 } 13772 } else { 13773 /* 13774 * No package verification is enabled, so immediately start 13775 * the remote call to initiate copy using temporary file. 13776 */ 13777 ret = args.copyApk(mContainerService, true); 13778 } 13779 } 13780 13781 mRet = ret; 13782 } 13783 13784 @Override 13785 void handleReturnCode() { 13786 // If mArgs is null, then MCS couldn't be reached. When it 13787 // reconnects, it will try again to install. At that point, this 13788 // will succeed. 13789 if (mArgs != null) { 13790 processPendingInstall(mArgs, mRet); 13791 } 13792 } 13793 13794 @Override 13795 void handleServiceError() { 13796 mArgs = createInstallArgs(this); 13797 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13798 } 13799 13800 public boolean isForwardLocked() { 13801 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13802 } 13803 } 13804 13805 /** 13806 * Used during creation of InstallArgs 13807 * 13808 * @param installFlags package installation flags 13809 * @return true if should be installed on external storage 13810 */ 13811 private static boolean installOnExternalAsec(int installFlags) { 13812 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 13813 return false; 13814 } 13815 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 13816 return true; 13817 } 13818 return false; 13819 } 13820 13821 /** 13822 * Used during creation of InstallArgs 13823 * 13824 * @param installFlags package installation flags 13825 * @return true if should be installed as forward locked 13826 */ 13827 private static boolean installForwardLocked(int installFlags) { 13828 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13829 } 13830 13831 private InstallArgs createInstallArgs(InstallParams params) { 13832 if (params.move != null) { 13833 return new MoveInstallArgs(params); 13834 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 13835 return new AsecInstallArgs(params); 13836 } else { 13837 return new FileInstallArgs(params); 13838 } 13839 } 13840 13841 /** 13842 * Create args that describe an existing installed package. Typically used 13843 * when cleaning up old installs, or used as a move source. 13844 */ 13845 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 13846 String resourcePath, String[] instructionSets) { 13847 final boolean isInAsec; 13848 if (installOnExternalAsec(installFlags)) { 13849 /* Apps on SD card are always in ASEC containers. */ 13850 isInAsec = true; 13851 } else if (installForwardLocked(installFlags) 13852 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 13853 /* 13854 * Forward-locked apps are only in ASEC containers if they're the 13855 * new style 13856 */ 13857 isInAsec = true; 13858 } else { 13859 isInAsec = false; 13860 } 13861 13862 if (isInAsec) { 13863 return new AsecInstallArgs(codePath, instructionSets, 13864 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 13865 } else { 13866 return new FileInstallArgs(codePath, resourcePath, instructionSets); 13867 } 13868 } 13869 13870 static abstract class InstallArgs { 13871 /** @see InstallParams#origin */ 13872 final OriginInfo origin; 13873 /** @see InstallParams#move */ 13874 final MoveInfo move; 13875 13876 final IPackageInstallObserver2 observer; 13877 // Always refers to PackageManager flags only 13878 final int installFlags; 13879 final String installerPackageName; 13880 final String volumeUuid; 13881 final UserHandle user; 13882 final String abiOverride; 13883 final String[] installGrantPermissions; 13884 /** If non-null, drop an async trace when the install completes */ 13885 final String traceMethod; 13886 final int traceCookie; 13887 final Certificate[][] certificates; 13888 final int installReason; 13889 13890 // The list of instruction sets supported by this app. This is currently 13891 // only used during the rmdex() phase to clean up resources. We can get rid of this 13892 // if we move dex files under the common app path. 13893 /* nullable */ String[] instructionSets; 13894 13895 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 13896 int installFlags, String installerPackageName, String volumeUuid, 13897 UserHandle user, String[] instructionSets, 13898 String abiOverride, String[] installGrantPermissions, 13899 String traceMethod, int traceCookie, Certificate[][] certificates, 13900 int installReason) { 13901 this.origin = origin; 13902 this.move = move; 13903 this.installFlags = installFlags; 13904 this.observer = observer; 13905 this.installerPackageName = installerPackageName; 13906 this.volumeUuid = volumeUuid; 13907 this.user = user; 13908 this.instructionSets = instructionSets; 13909 this.abiOverride = abiOverride; 13910 this.installGrantPermissions = installGrantPermissions; 13911 this.traceMethod = traceMethod; 13912 this.traceCookie = traceCookie; 13913 this.certificates = certificates; 13914 this.installReason = installReason; 13915 } 13916 13917 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 13918 abstract int doPreInstall(int status); 13919 13920 /** 13921 * Rename package into final resting place. All paths on the given 13922 * scanned package should be updated to reflect the rename. 13923 */ 13924 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 13925 abstract int doPostInstall(int status, int uid); 13926 13927 /** @see PackageSettingBase#codePathString */ 13928 abstract String getCodePath(); 13929 /** @see PackageSettingBase#resourcePathString */ 13930 abstract String getResourcePath(); 13931 13932 // Need installer lock especially for dex file removal. 13933 abstract void cleanUpResourcesLI(); 13934 abstract boolean doPostDeleteLI(boolean delete); 13935 13936 /** 13937 * Called before the source arguments are copied. This is used mostly 13938 * for MoveParams when it needs to read the source file to put it in the 13939 * destination. 13940 */ 13941 int doPreCopy() { 13942 return PackageManager.INSTALL_SUCCEEDED; 13943 } 13944 13945 /** 13946 * Called after the source arguments are copied. This is used mostly for 13947 * MoveParams when it needs to read the source file to put it in the 13948 * destination. 13949 */ 13950 int doPostCopy(int uid) { 13951 return PackageManager.INSTALL_SUCCEEDED; 13952 } 13953 13954 protected boolean isFwdLocked() { 13955 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13956 } 13957 13958 protected boolean isExternalAsec() { 13959 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13960 } 13961 13962 protected boolean isEphemeral() { 13963 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13964 } 13965 13966 UserHandle getUser() { 13967 return user; 13968 } 13969 } 13970 13971 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 13972 if (!allCodePaths.isEmpty()) { 13973 if (instructionSets == null) { 13974 throw new IllegalStateException("instructionSet == null"); 13975 } 13976 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 13977 for (String codePath : allCodePaths) { 13978 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 13979 try { 13980 mInstaller.rmdex(codePath, dexCodeInstructionSet); 13981 } catch (InstallerException ignored) { 13982 } 13983 } 13984 } 13985 } 13986 } 13987 13988 /** 13989 * Logic to handle installation of non-ASEC applications, including copying 13990 * and renaming logic. 13991 */ 13992 class FileInstallArgs extends InstallArgs { 13993 private File codeFile; 13994 private File resourceFile; 13995 13996 // Example topology: 13997 // /data/app/com.example/base.apk 13998 // /data/app/com.example/split_foo.apk 13999 // /data/app/com.example/lib/arm/libfoo.so 14000 // /data/app/com.example/lib/arm64/libfoo.so 14001 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 14002 14003 /** New install */ 14004 FileInstallArgs(InstallParams params) { 14005 super(params.origin, params.move, params.observer, params.installFlags, 14006 params.installerPackageName, params.volumeUuid, 14007 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 14008 params.grantedRuntimePermissions, 14009 params.traceMethod, params.traceCookie, params.certificates, 14010 params.installReason); 14011 if (isFwdLocked()) { 14012 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 14013 } 14014 } 14015 14016 /** Existing install */ 14017 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 14018 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 14019 null, null, null, 0, null /*certificates*/, 14020 PackageManager.INSTALL_REASON_UNKNOWN); 14021 this.codeFile = (codePath != null) ? new File(codePath) : null; 14022 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 14023 } 14024 14025 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14026 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 14027 try { 14028 return doCopyApk(imcs, temp); 14029 } finally { 14030 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14031 } 14032 } 14033 14034 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14035 if (origin.staged) { 14036 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 14037 codeFile = origin.file; 14038 resourceFile = origin.file; 14039 return PackageManager.INSTALL_SUCCEEDED; 14040 } 14041 14042 try { 14043 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 14044 final File tempDir = 14045 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 14046 codeFile = tempDir; 14047 resourceFile = tempDir; 14048 } catch (IOException e) { 14049 Slog.w(TAG, "Failed to create copy file: " + e); 14050 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 14051 } 14052 14053 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 14054 @Override 14055 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 14056 if (!FileUtils.isValidExtFilename(name)) { 14057 throw new IllegalArgumentException("Invalid filename: " + name); 14058 } 14059 try { 14060 final File file = new File(codeFile, name); 14061 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 14062 O_RDWR | O_CREAT, 0644); 14063 Os.chmod(file.getAbsolutePath(), 0644); 14064 return new ParcelFileDescriptor(fd); 14065 } catch (ErrnoException e) { 14066 throw new RemoteException("Failed to open: " + e.getMessage()); 14067 } 14068 } 14069 }; 14070 14071 int ret = PackageManager.INSTALL_SUCCEEDED; 14072 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 14073 if (ret != PackageManager.INSTALL_SUCCEEDED) { 14074 Slog.e(TAG, "Failed to copy package"); 14075 return ret; 14076 } 14077 14078 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 14079 NativeLibraryHelper.Handle handle = null; 14080 try { 14081 handle = NativeLibraryHelper.Handle.create(codeFile); 14082 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 14083 abiOverride); 14084 } catch (IOException e) { 14085 Slog.e(TAG, "Copying native libraries failed", e); 14086 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 14087 } finally { 14088 IoUtils.closeQuietly(handle); 14089 } 14090 14091 return ret; 14092 } 14093 14094 int doPreInstall(int status) { 14095 if (status != PackageManager.INSTALL_SUCCEEDED) { 14096 cleanUp(); 14097 } 14098 return status; 14099 } 14100 14101 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 14102 if (status != PackageManager.INSTALL_SUCCEEDED) { 14103 cleanUp(); 14104 return false; 14105 } 14106 14107 final File targetDir = codeFile.getParentFile(); 14108 final File beforeCodeFile = codeFile; 14109 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 14110 14111 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 14112 try { 14113 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 14114 } catch (ErrnoException e) { 14115 Slog.w(TAG, "Failed to rename", e); 14116 return false; 14117 } 14118 14119 if (!SELinux.restoreconRecursive(afterCodeFile)) { 14120 Slog.w(TAG, "Failed to restorecon"); 14121 return false; 14122 } 14123 14124 // Reflect the rename internally 14125 codeFile = afterCodeFile; 14126 resourceFile = afterCodeFile; 14127 14128 // Reflect the rename in scanned details 14129 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 14130 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 14131 afterCodeFile, pkg.baseCodePath)); 14132 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 14133 afterCodeFile, pkg.splitCodePaths)); 14134 14135 // Reflect the rename in app info 14136 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 14137 pkg.setApplicationInfoCodePath(pkg.codePath); 14138 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 14139 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 14140 pkg.setApplicationInfoResourcePath(pkg.codePath); 14141 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 14142 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 14143 14144 return true; 14145 } 14146 14147 int doPostInstall(int status, int uid) { 14148 if (status != PackageManager.INSTALL_SUCCEEDED) { 14149 cleanUp(); 14150 } 14151 return status; 14152 } 14153 14154 @Override 14155 String getCodePath() { 14156 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 14157 } 14158 14159 @Override 14160 String getResourcePath() { 14161 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 14162 } 14163 14164 private boolean cleanUp() { 14165 if (codeFile == null || !codeFile.exists()) { 14166 return false; 14167 } 14168 14169 removeCodePathLI(codeFile); 14170 14171 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 14172 resourceFile.delete(); 14173 } 14174 14175 return true; 14176 } 14177 14178 void cleanUpResourcesLI() { 14179 // Try enumerating all code paths before deleting 14180 List<String> allCodePaths = Collections.EMPTY_LIST; 14181 if (codeFile != null && codeFile.exists()) { 14182 try { 14183 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 14184 allCodePaths = pkg.getAllCodePaths(); 14185 } catch (PackageParserException e) { 14186 // Ignored; we tried our best 14187 } 14188 } 14189 14190 cleanUp(); 14191 removeDexFiles(allCodePaths, instructionSets); 14192 } 14193 14194 boolean doPostDeleteLI(boolean delete) { 14195 // XXX err, shouldn't we respect the delete flag? 14196 cleanUpResourcesLI(); 14197 return true; 14198 } 14199 } 14200 14201 private boolean isAsecExternal(String cid) { 14202 final String asecPath = PackageHelper.getSdFilesystem(cid); 14203 return !asecPath.startsWith(mAsecInternalPath); 14204 } 14205 14206 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 14207 PackageManagerException { 14208 if (copyRet < 0) { 14209 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 14210 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 14211 throw new PackageManagerException(copyRet, message); 14212 } 14213 } 14214 } 14215 14216 /** 14217 * Extract the StorageManagerService "container ID" from the full code path of an 14218 * .apk. 14219 */ 14220 static String cidFromCodePath(String fullCodePath) { 14221 int eidx = fullCodePath.lastIndexOf("/"); 14222 String subStr1 = fullCodePath.substring(0, eidx); 14223 int sidx = subStr1.lastIndexOf("/"); 14224 return subStr1.substring(sidx+1, eidx); 14225 } 14226 14227 /** 14228 * Logic to handle installation of ASEC applications, including copying and 14229 * renaming logic. 14230 */ 14231 class AsecInstallArgs extends InstallArgs { 14232 static final String RES_FILE_NAME = "pkg.apk"; 14233 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 14234 14235 String cid; 14236 String packagePath; 14237 String resourcePath; 14238 14239 /** New install */ 14240 AsecInstallArgs(InstallParams params) { 14241 super(params.origin, params.move, params.observer, params.installFlags, 14242 params.installerPackageName, params.volumeUuid, 14243 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 14244 params.grantedRuntimePermissions, 14245 params.traceMethod, params.traceCookie, params.certificates, 14246 params.installReason); 14247 } 14248 14249 /** Existing install */ 14250 AsecInstallArgs(String fullCodePath, String[] instructionSets, 14251 boolean isExternal, boolean isForwardLocked) { 14252 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 14253 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 14254 instructionSets, null, null, null, 0, null /*certificates*/, 14255 PackageManager.INSTALL_REASON_UNKNOWN); 14256 // Hackily pretend we're still looking at a full code path 14257 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 14258 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 14259 } 14260 14261 // Extract cid from fullCodePath 14262 int eidx = fullCodePath.lastIndexOf("/"); 14263 String subStr1 = fullCodePath.substring(0, eidx); 14264 int sidx = subStr1.lastIndexOf("/"); 14265 cid = subStr1.substring(sidx+1, eidx); 14266 setMountPath(subStr1); 14267 } 14268 14269 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 14270 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 14271 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 14272 instructionSets, null, null, null, 0, null /*certificates*/, 14273 PackageManager.INSTALL_REASON_UNKNOWN); 14274 this.cid = cid; 14275 setMountPath(PackageHelper.getSdDir(cid)); 14276 } 14277 14278 void createCopyFile() { 14279 cid = mInstallerService.allocateExternalStageCidLegacy(); 14280 } 14281 14282 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 14283 if (origin.staged && origin.cid != null) { 14284 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 14285 cid = origin.cid; 14286 setMountPath(PackageHelper.getSdDir(cid)); 14287 return PackageManager.INSTALL_SUCCEEDED; 14288 } 14289 14290 if (temp) { 14291 createCopyFile(); 14292 } else { 14293 /* 14294 * Pre-emptively destroy the container since it's destroyed if 14295 * copying fails due to it existing anyway. 14296 */ 14297 PackageHelper.destroySdDir(cid); 14298 } 14299 14300 final String newMountPath = imcs.copyPackageToContainer( 14301 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 14302 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 14303 14304 if (newMountPath != null) { 14305 setMountPath(newMountPath); 14306 return PackageManager.INSTALL_SUCCEEDED; 14307 } else { 14308 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14309 } 14310 } 14311 14312 @Override 14313 String getCodePath() { 14314 return packagePath; 14315 } 14316 14317 @Override 14318 String getResourcePath() { 14319 return resourcePath; 14320 } 14321 14322 int doPreInstall(int status) { 14323 if (status != PackageManager.INSTALL_SUCCEEDED) { 14324 // Destroy container 14325 PackageHelper.destroySdDir(cid); 14326 } else { 14327 boolean mounted = PackageHelper.isContainerMounted(cid); 14328 if (!mounted) { 14329 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 14330 Process.SYSTEM_UID); 14331 if (newMountPath != null) { 14332 setMountPath(newMountPath); 14333 } else { 14334 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14335 } 14336 } 14337 } 14338 return status; 14339 } 14340 14341 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 14342 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 14343 String newMountPath = null; 14344 if (PackageHelper.isContainerMounted(cid)) { 14345 // Unmount the container 14346 if (!PackageHelper.unMountSdDir(cid)) { 14347 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 14348 return false; 14349 } 14350 } 14351 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 14352 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 14353 " which might be stale. Will try to clean up."); 14354 // Clean up the stale container and proceed to recreate. 14355 if (!PackageHelper.destroySdDir(newCacheId)) { 14356 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 14357 return false; 14358 } 14359 // Successfully cleaned up stale container. Try to rename again. 14360 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 14361 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 14362 + " inspite of cleaning it up."); 14363 return false; 14364 } 14365 } 14366 if (!PackageHelper.isContainerMounted(newCacheId)) { 14367 Slog.w(TAG, "Mounting container " + newCacheId); 14368 newMountPath = PackageHelper.mountSdDir(newCacheId, 14369 getEncryptKey(), Process.SYSTEM_UID); 14370 } else { 14371 newMountPath = PackageHelper.getSdDir(newCacheId); 14372 } 14373 if (newMountPath == null) { 14374 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 14375 return false; 14376 } 14377 Log.i(TAG, "Succesfully renamed " + cid + 14378 " to " + newCacheId + 14379 " at new path: " + newMountPath); 14380 cid = newCacheId; 14381 14382 final File beforeCodeFile = new File(packagePath); 14383 setMountPath(newMountPath); 14384 final File afterCodeFile = new File(packagePath); 14385 14386 // Reflect the rename in scanned details 14387 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 14388 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 14389 afterCodeFile, pkg.baseCodePath)); 14390 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 14391 afterCodeFile, pkg.splitCodePaths)); 14392 14393 // Reflect the rename in app info 14394 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 14395 pkg.setApplicationInfoCodePath(pkg.codePath); 14396 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 14397 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 14398 pkg.setApplicationInfoResourcePath(pkg.codePath); 14399 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 14400 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 14401 14402 return true; 14403 } 14404 14405 private void setMountPath(String mountPath) { 14406 final File mountFile = new File(mountPath); 14407 14408 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 14409 if (monolithicFile.exists()) { 14410 packagePath = monolithicFile.getAbsolutePath(); 14411 if (isFwdLocked()) { 14412 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 14413 } else { 14414 resourcePath = packagePath; 14415 } 14416 } else { 14417 packagePath = mountFile.getAbsolutePath(); 14418 resourcePath = packagePath; 14419 } 14420 } 14421 14422 int doPostInstall(int status, int uid) { 14423 if (status != PackageManager.INSTALL_SUCCEEDED) { 14424 cleanUp(); 14425 } else { 14426 final int groupOwner; 14427 final String protectedFile; 14428 if (isFwdLocked()) { 14429 groupOwner = UserHandle.getSharedAppGid(uid); 14430 protectedFile = RES_FILE_NAME; 14431 } else { 14432 groupOwner = -1; 14433 protectedFile = null; 14434 } 14435 14436 if (uid < Process.FIRST_APPLICATION_UID 14437 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 14438 Slog.e(TAG, "Failed to finalize " + cid); 14439 PackageHelper.destroySdDir(cid); 14440 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14441 } 14442 14443 boolean mounted = PackageHelper.isContainerMounted(cid); 14444 if (!mounted) { 14445 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 14446 } 14447 } 14448 return status; 14449 } 14450 14451 private void cleanUp() { 14452 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 14453 14454 // Destroy secure container 14455 PackageHelper.destroySdDir(cid); 14456 } 14457 14458 private List<String> getAllCodePaths() { 14459 final File codeFile = new File(getCodePath()); 14460 if (codeFile != null && codeFile.exists()) { 14461 try { 14462 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 14463 return pkg.getAllCodePaths(); 14464 } catch (PackageParserException e) { 14465 // Ignored; we tried our best 14466 } 14467 } 14468 return Collections.EMPTY_LIST; 14469 } 14470 14471 void cleanUpResourcesLI() { 14472 // Enumerate all code paths before deleting 14473 cleanUpResourcesLI(getAllCodePaths()); 14474 } 14475 14476 private void cleanUpResourcesLI(List<String> allCodePaths) { 14477 cleanUp(); 14478 removeDexFiles(allCodePaths, instructionSets); 14479 } 14480 14481 String getPackageName() { 14482 return getAsecPackageName(cid); 14483 } 14484 14485 boolean doPostDeleteLI(boolean delete) { 14486 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 14487 final List<String> allCodePaths = getAllCodePaths(); 14488 boolean mounted = PackageHelper.isContainerMounted(cid); 14489 if (mounted) { 14490 // Unmount first 14491 if (PackageHelper.unMountSdDir(cid)) { 14492 mounted = false; 14493 } 14494 } 14495 if (!mounted && delete) { 14496 cleanUpResourcesLI(allCodePaths); 14497 } 14498 return !mounted; 14499 } 14500 14501 @Override 14502 int doPreCopy() { 14503 if (isFwdLocked()) { 14504 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 14505 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 14506 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14507 } 14508 } 14509 14510 return PackageManager.INSTALL_SUCCEEDED; 14511 } 14512 14513 @Override 14514 int doPostCopy(int uid) { 14515 if (isFwdLocked()) { 14516 if (uid < Process.FIRST_APPLICATION_UID 14517 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 14518 RES_FILE_NAME)) { 14519 Slog.e(TAG, "Failed to finalize " + cid); 14520 PackageHelper.destroySdDir(cid); 14521 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14522 } 14523 } 14524 14525 return PackageManager.INSTALL_SUCCEEDED; 14526 } 14527 } 14528 14529 /** 14530 * Logic to handle movement of existing installed applications. 14531 */ 14532 class MoveInstallArgs extends InstallArgs { 14533 private File codeFile; 14534 private File resourceFile; 14535 14536 /** New install */ 14537 MoveInstallArgs(InstallParams params) { 14538 super(params.origin, params.move, params.observer, params.installFlags, 14539 params.installerPackageName, params.volumeUuid, 14540 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 14541 params.grantedRuntimePermissions, 14542 params.traceMethod, params.traceCookie, params.certificates, 14543 params.installReason); 14544 } 14545 14546 int copyApk(IMediaContainerService imcs, boolean temp) { 14547 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 14548 + move.fromUuid + " to " + move.toUuid); 14549 synchronized (mInstaller) { 14550 try { 14551 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 14552 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 14553 } catch (InstallerException e) { 14554 Slog.w(TAG, "Failed to move app", e); 14555 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 14556 } 14557 } 14558 14559 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 14560 resourceFile = codeFile; 14561 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 14562 14563 return PackageManager.INSTALL_SUCCEEDED; 14564 } 14565 14566 int doPreInstall(int status) { 14567 if (status != PackageManager.INSTALL_SUCCEEDED) { 14568 cleanUp(move.toUuid); 14569 } 14570 return status; 14571 } 14572 14573 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 14574 if (status != PackageManager.INSTALL_SUCCEEDED) { 14575 cleanUp(move.toUuid); 14576 return false; 14577 } 14578 14579 // Reflect the move in app info 14580 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 14581 pkg.setApplicationInfoCodePath(pkg.codePath); 14582 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 14583 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 14584 pkg.setApplicationInfoResourcePath(pkg.codePath); 14585 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 14586 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 14587 14588 return true; 14589 } 14590 14591 int doPostInstall(int status, int uid) { 14592 if (status == PackageManager.INSTALL_SUCCEEDED) { 14593 cleanUp(move.fromUuid); 14594 } else { 14595 cleanUp(move.toUuid); 14596 } 14597 return status; 14598 } 14599 14600 @Override 14601 String getCodePath() { 14602 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 14603 } 14604 14605 @Override 14606 String getResourcePath() { 14607 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 14608 } 14609 14610 private boolean cleanUp(String volumeUuid) { 14611 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 14612 move.dataAppName); 14613 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 14614 final int[] userIds = sUserManager.getUserIds(); 14615 synchronized (mInstallLock) { 14616 // Clean up both app data and code 14617 // All package moves are frozen until finished 14618 for (int userId : userIds) { 14619 try { 14620 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 14621 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 14622 } catch (InstallerException e) { 14623 Slog.w(TAG, String.valueOf(e)); 14624 } 14625 } 14626 removeCodePathLI(codeFile); 14627 } 14628 return true; 14629 } 14630 14631 void cleanUpResourcesLI() { 14632 throw new UnsupportedOperationException(); 14633 } 14634 14635 boolean doPostDeleteLI(boolean delete) { 14636 throw new UnsupportedOperationException(); 14637 } 14638 } 14639 14640 static String getAsecPackageName(String packageCid) { 14641 int idx = packageCid.lastIndexOf("-"); 14642 if (idx == -1) { 14643 return packageCid; 14644 } 14645 return packageCid.substring(0, idx); 14646 } 14647 14648 // Utility method used to create code paths based on package name and available index. 14649 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 14650 String idxStr = ""; 14651 int idx = 1; 14652 // Fall back to default value of idx=1 if prefix is not 14653 // part of oldCodePath 14654 if (oldCodePath != null) { 14655 String subStr = oldCodePath; 14656 // Drop the suffix right away 14657 if (suffix != null && subStr.endsWith(suffix)) { 14658 subStr = subStr.substring(0, subStr.length() - suffix.length()); 14659 } 14660 // If oldCodePath already contains prefix find out the 14661 // ending index to either increment or decrement. 14662 int sidx = subStr.lastIndexOf(prefix); 14663 if (sidx != -1) { 14664 subStr = subStr.substring(sidx + prefix.length()); 14665 if (subStr != null) { 14666 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 14667 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 14668 } 14669 try { 14670 idx = Integer.parseInt(subStr); 14671 if (idx <= 1) { 14672 idx++; 14673 } else { 14674 idx--; 14675 } 14676 } catch(NumberFormatException e) { 14677 } 14678 } 14679 } 14680 } 14681 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 14682 return prefix + idxStr; 14683 } 14684 14685 private File getNextCodePath(File targetDir, String packageName) { 14686 File result; 14687 SecureRandom random = new SecureRandom(); 14688 byte[] bytes = new byte[16]; 14689 do { 14690 random.nextBytes(bytes); 14691 String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP); 14692 result = new File(targetDir, packageName + "-" + suffix); 14693 } while (result.exists()); 14694 return result; 14695 } 14696 14697 // Utility method that returns the relative package path with respect 14698 // to the installation directory. Like say for /data/data/com.test-1.apk 14699 // string com.test-1 is returned. 14700 static String deriveCodePathName(String codePath) { 14701 if (codePath == null) { 14702 return null; 14703 } 14704 final File codeFile = new File(codePath); 14705 final String name = codeFile.getName(); 14706 if (codeFile.isDirectory()) { 14707 return name; 14708 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 14709 final int lastDot = name.lastIndexOf('.'); 14710 return name.substring(0, lastDot); 14711 } else { 14712 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 14713 return null; 14714 } 14715 } 14716 14717 static class PackageInstalledInfo { 14718 String name; 14719 int uid; 14720 // The set of users that originally had this package installed. 14721 int[] origUsers; 14722 // The set of users that now have this package installed. 14723 int[] newUsers; 14724 PackageParser.Package pkg; 14725 int returnCode; 14726 String returnMsg; 14727 PackageRemovedInfo removedInfo; 14728 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 14729 14730 public void setError(int code, String msg) { 14731 setReturnCode(code); 14732 setReturnMessage(msg); 14733 Slog.w(TAG, msg); 14734 } 14735 14736 public void setError(String msg, PackageParserException e) { 14737 setReturnCode(e.error); 14738 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14739 Slog.w(TAG, msg, e); 14740 } 14741 14742 public void setError(String msg, PackageManagerException e) { 14743 returnCode = e.error; 14744 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14745 Slog.w(TAG, msg, e); 14746 } 14747 14748 public void setReturnCode(int returnCode) { 14749 this.returnCode = returnCode; 14750 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14751 for (int i = 0; i < childCount; i++) { 14752 addedChildPackages.valueAt(i).returnCode = returnCode; 14753 } 14754 } 14755 14756 private void setReturnMessage(String returnMsg) { 14757 this.returnMsg = returnMsg; 14758 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14759 for (int i = 0; i < childCount; i++) { 14760 addedChildPackages.valueAt(i).returnMsg = returnMsg; 14761 } 14762 } 14763 14764 // In some error cases we want to convey more info back to the observer 14765 String origPackage; 14766 String origPermission; 14767 } 14768 14769 /* 14770 * Install a non-existing package. 14771 */ 14772 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 14773 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 14774 PackageInstalledInfo res, int installReason) { 14775 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 14776 14777 // Remember this for later, in case we need to rollback this install 14778 String pkgName = pkg.packageName; 14779 14780 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 14781 14782 synchronized(mPackages) { 14783 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName); 14784 if (renamedPackage != null) { 14785 // A package with the same name is already installed, though 14786 // it has been renamed to an older name. The package we 14787 // are trying to install should be installed as an update to 14788 // the existing one, but that has not been requested, so bail. 14789 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14790 + " without first uninstalling package running as " 14791 + renamedPackage); 14792 return; 14793 } 14794 if (mPackages.containsKey(pkgName)) { 14795 // Don't allow installation over an existing package with the same name. 14796 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14797 + " without first uninstalling."); 14798 return; 14799 } 14800 } 14801 14802 try { 14803 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 14804 System.currentTimeMillis(), user); 14805 14806 updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason); 14807 14808 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14809 prepareAppDataAfterInstallLIF(newPackage); 14810 14811 } else { 14812 // Remove package from internal structures, but keep around any 14813 // data that might have already existed 14814 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 14815 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 14816 } 14817 } catch (PackageManagerException e) { 14818 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14819 } 14820 14821 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14822 } 14823 14824 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 14825 // Can't rotate keys during boot or if sharedUser. 14826 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 14827 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 14828 return false; 14829 } 14830 // app is using upgradeKeySets; make sure all are valid 14831 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14832 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 14833 for (int i = 0; i < upgradeKeySets.length; i++) { 14834 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 14835 Slog.wtf(TAG, "Package " 14836 + (oldPs.name != null ? oldPs.name : "<null>") 14837 + " contains upgrade-key-set reference to unknown key-set: " 14838 + upgradeKeySets[i] 14839 + " reverting to signatures check."); 14840 return false; 14841 } 14842 } 14843 return true; 14844 } 14845 14846 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 14847 // Upgrade keysets are being used. Determine if new package has a superset of the 14848 // required keys. 14849 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 14850 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14851 for (int i = 0; i < upgradeKeySets.length; i++) { 14852 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 14853 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 14854 return true; 14855 } 14856 } 14857 return false; 14858 } 14859 14860 private static void updateDigest(MessageDigest digest, File file) throws IOException { 14861 try (DigestInputStream digestStream = 14862 new DigestInputStream(new FileInputStream(file), digest)) { 14863 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 14864 } 14865 } 14866 14867 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 14868 UserHandle user, String installerPackageName, PackageInstalledInfo res, 14869 int installReason) { 14870 final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 14871 14872 final PackageParser.Package oldPackage; 14873 final String pkgName = pkg.packageName; 14874 final int[] allUsers; 14875 final int[] installedUsers; 14876 14877 synchronized(mPackages) { 14878 oldPackage = mPackages.get(pkgName); 14879 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 14880 14881 // don't allow upgrade to target a release SDK from a pre-release SDK 14882 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 14883 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14884 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 14885 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14886 if (oldTargetsPreRelease 14887 && !newTargetsPreRelease 14888 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 14889 Slog.w(TAG, "Can't install package targeting released sdk"); 14890 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 14891 return; 14892 } 14893 14894 // don't allow an upgrade from full to ephemeral 14895 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 14896 if (isEphemeral && !oldIsEphemeral) { 14897 // can't downgrade from full to ephemeral 14898 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 14899 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14900 return; 14901 } 14902 14903 // verify signatures are valid 14904 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14905 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14906 if (!checkUpgradeKeySetLP(ps, pkg)) { 14907 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14908 "New package not signed by keys specified by upgrade-keysets: " 14909 + pkgName); 14910 return; 14911 } 14912 } else { 14913 // default to original signature matching 14914 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 14915 != PackageManager.SIGNATURE_MATCH) { 14916 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14917 "New package has a different signature: " + pkgName); 14918 return; 14919 } 14920 } 14921 14922 // don't allow a system upgrade unless the upgrade hash matches 14923 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 14924 byte[] digestBytes = null; 14925 try { 14926 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 14927 updateDigest(digest, new File(pkg.baseCodePath)); 14928 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 14929 for (String path : pkg.splitCodePaths) { 14930 updateDigest(digest, new File(path)); 14931 } 14932 } 14933 digestBytes = digest.digest(); 14934 } catch (NoSuchAlgorithmException | IOException e) { 14935 res.setError(INSTALL_FAILED_INVALID_APK, 14936 "Could not compute hash: " + pkgName); 14937 return; 14938 } 14939 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 14940 res.setError(INSTALL_FAILED_INVALID_APK, 14941 "New package fails restrict-update check: " + pkgName); 14942 return; 14943 } 14944 // retain upgrade restriction 14945 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 14946 } 14947 14948 // Check for shared user id changes 14949 String invalidPackageName = 14950 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 14951 if (invalidPackageName != null) { 14952 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 14953 "Package " + invalidPackageName + " tried to change user " 14954 + oldPackage.mSharedUserId); 14955 return; 14956 } 14957 14958 // In case of rollback, remember per-user/profile install state 14959 allUsers = sUserManager.getUserIds(); 14960 installedUsers = ps.queryInstalledUsers(allUsers, true); 14961 } 14962 14963 // Update what is removed 14964 res.removedInfo = new PackageRemovedInfo(); 14965 res.removedInfo.uid = oldPackage.applicationInfo.uid; 14966 res.removedInfo.removedPackage = oldPackage.packageName; 14967 res.removedInfo.isUpdate = true; 14968 res.removedInfo.origUsers = installedUsers; 14969 final PackageSetting ps = mSettings.getPackageLPr(pkgName); 14970 res.removedInfo.installReasons = new SparseArray<>(installedUsers.length); 14971 for (int i = 0; i < installedUsers.length; i++) { 14972 final int userId = installedUsers[i]; 14973 res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId)); 14974 } 14975 14976 final int childCount = (oldPackage.childPackages != null) 14977 ? oldPackage.childPackages.size() : 0; 14978 for (int i = 0; i < childCount; i++) { 14979 boolean childPackageUpdated = false; 14980 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 14981 final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 14982 if (res.addedChildPackages != null) { 14983 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14984 if (childRes != null) { 14985 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 14986 childRes.removedInfo.removedPackage = childPkg.packageName; 14987 childRes.removedInfo.isUpdate = true; 14988 childRes.removedInfo.installReasons = res.removedInfo.installReasons; 14989 childPackageUpdated = true; 14990 } 14991 } 14992 if (!childPackageUpdated) { 14993 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 14994 childRemovedRes.removedPackage = childPkg.packageName; 14995 childRemovedRes.isUpdate = false; 14996 childRemovedRes.dataRemoved = true; 14997 synchronized (mPackages) { 14998 if (childPs != null) { 14999 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 15000 } 15001 } 15002 if (res.removedInfo.removedChildPackages == null) { 15003 res.removedInfo.removedChildPackages = new ArrayMap<>(); 15004 } 15005 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 15006 } 15007 } 15008 15009 boolean sysPkg = (isSystemApp(oldPackage)); 15010 if (sysPkg) { 15011 // Set the system/privileged flags as needed 15012 final boolean privileged = 15013 (oldPackage.applicationInfo.privateFlags 15014 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15015 final int systemPolicyFlags = policyFlags 15016 | PackageParser.PARSE_IS_SYSTEM 15017 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 15018 15019 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 15020 user, allUsers, installerPackageName, res, installReason); 15021 } else { 15022 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 15023 user, allUsers, installerPackageName, res, installReason); 15024 } 15025 } 15026 15027 public List<String> getPreviousCodePaths(String packageName) { 15028 final PackageSetting ps = mSettings.mPackages.get(packageName); 15029 final List<String> result = new ArrayList<String>(); 15030 if (ps != null && ps.oldCodePaths != null) { 15031 result.addAll(ps.oldCodePaths); 15032 } 15033 return result; 15034 } 15035 15036 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 15037 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 15038 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 15039 int installReason) { 15040 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 15041 + deletedPackage); 15042 15043 String pkgName = deletedPackage.packageName; 15044 boolean deletedPkg = true; 15045 boolean addedPkg = false; 15046 boolean updatedSettings = false; 15047 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 15048 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 15049 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 15050 15051 final long origUpdateTime = (pkg.mExtras != null) 15052 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 15053 15054 // First delete the existing package while retaining the data directory 15055 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 15056 res.removedInfo, true, pkg)) { 15057 // If the existing package wasn't successfully deleted 15058 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 15059 deletedPkg = false; 15060 } else { 15061 // Successfully deleted the old package; proceed with replace. 15062 15063 // If deleted package lived in a container, give users a chance to 15064 // relinquish resources before killing. 15065 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 15066 if (DEBUG_INSTALL) { 15067 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 15068 } 15069 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 15070 final ArrayList<String> pkgList = new ArrayList<String>(1); 15071 pkgList.add(deletedPackage.applicationInfo.packageName); 15072 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 15073 } 15074 15075 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 15076 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 15077 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 15078 15079 try { 15080 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 15081 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 15082 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 15083 installReason); 15084 15085 // Update the in-memory copy of the previous code paths. 15086 PackageSetting ps = mSettings.mPackages.get(pkgName); 15087 if (!killApp) { 15088 if (ps.oldCodePaths == null) { 15089 ps.oldCodePaths = new ArraySet<>(); 15090 } 15091 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 15092 if (deletedPackage.splitCodePaths != null) { 15093 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 15094 } 15095 } else { 15096 ps.oldCodePaths = null; 15097 } 15098 if (ps.childPackageNames != null) { 15099 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 15100 final String childPkgName = ps.childPackageNames.get(i); 15101 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 15102 childPs.oldCodePaths = ps.oldCodePaths; 15103 } 15104 } 15105 prepareAppDataAfterInstallLIF(newPackage); 15106 addedPkg = true; 15107 } catch (PackageManagerException e) { 15108 res.setError("Package couldn't be installed in " + pkg.codePath, e); 15109 } 15110 } 15111 15112 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 15113 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 15114 15115 // Revert all internal state mutations and added folders for the failed install 15116 if (addedPkg) { 15117 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 15118 res.removedInfo, true, null); 15119 } 15120 15121 // Restore the old package 15122 if (deletedPkg) { 15123 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 15124 File restoreFile = new File(deletedPackage.codePath); 15125 // Parse old package 15126 boolean oldExternal = isExternal(deletedPackage); 15127 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 15128 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 15129 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 15130 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 15131 try { 15132 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 15133 null); 15134 } catch (PackageManagerException e) { 15135 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 15136 + e.getMessage()); 15137 return; 15138 } 15139 15140 synchronized (mPackages) { 15141 // Ensure the installer package name up to date 15142 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 15143 15144 // Update permissions for restored package 15145 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 15146 15147 mSettings.writeLPr(); 15148 } 15149 15150 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 15151 } 15152 } else { 15153 synchronized (mPackages) { 15154 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName); 15155 if (ps != null) { 15156 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 15157 if (res.removedInfo.removedChildPackages != null) { 15158 final int childCount = res.removedInfo.removedChildPackages.size(); 15159 // Iterate in reverse as we may modify the collection 15160 for (int i = childCount - 1; i >= 0; i--) { 15161 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 15162 if (res.addedChildPackages.containsKey(childPackageName)) { 15163 res.removedInfo.removedChildPackages.removeAt(i); 15164 } else { 15165 PackageRemovedInfo childInfo = res.removedInfo 15166 .removedChildPackages.valueAt(i); 15167 childInfo.removedForAllUsers = mPackages.get( 15168 childInfo.removedPackage) == null; 15169 } 15170 } 15171 } 15172 } 15173 } 15174 } 15175 } 15176 15177 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 15178 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 15179 int[] allUsers, String installerPackageName, PackageInstalledInfo res, 15180 int installReason) { 15181 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 15182 + ", old=" + deletedPackage); 15183 15184 final boolean disabledSystem; 15185 15186 // Remove existing system package 15187 removePackageLI(deletedPackage, true); 15188 15189 synchronized (mPackages) { 15190 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 15191 } 15192 if (!disabledSystem) { 15193 // We didn't need to disable the .apk as a current system package, 15194 // which means we are replacing another update that is already 15195 // installed. We need to make sure to delete the older one's .apk. 15196 res.removedInfo.args = createInstallArgsForExisting(0, 15197 deletedPackage.applicationInfo.getCodePath(), 15198 deletedPackage.applicationInfo.getResourcePath(), 15199 getAppDexInstructionSets(deletedPackage.applicationInfo)); 15200 } else { 15201 res.removedInfo.args = null; 15202 } 15203 15204 // Successfully disabled the old package. Now proceed with re-installation 15205 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 15206 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 15207 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 15208 15209 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15210 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 15211 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 15212 15213 PackageParser.Package newPackage = null; 15214 try { 15215 // Add the package to the internal data structures 15216 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 15217 15218 // Set the update and install times 15219 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 15220 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 15221 System.currentTimeMillis()); 15222 15223 // Update the package dynamic state if succeeded 15224 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 15225 // Now that the install succeeded make sure we remove data 15226 // directories for any child package the update removed. 15227 final int deletedChildCount = (deletedPackage.childPackages != null) 15228 ? deletedPackage.childPackages.size() : 0; 15229 final int newChildCount = (newPackage.childPackages != null) 15230 ? newPackage.childPackages.size() : 0; 15231 for (int i = 0; i < deletedChildCount; i++) { 15232 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 15233 boolean childPackageDeleted = true; 15234 for (int j = 0; j < newChildCount; j++) { 15235 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 15236 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 15237 childPackageDeleted = false; 15238 break; 15239 } 15240 } 15241 if (childPackageDeleted) { 15242 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 15243 deletedChildPkg.packageName); 15244 if (ps != null && res.removedInfo.removedChildPackages != null) { 15245 PackageRemovedInfo removedChildRes = res.removedInfo 15246 .removedChildPackages.get(deletedChildPkg.packageName); 15247 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 15248 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 15249 } 15250 } 15251 } 15252 15253 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user, 15254 installReason); 15255 prepareAppDataAfterInstallLIF(newPackage); 15256 } 15257 } catch (PackageManagerException e) { 15258 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 15259 res.setError("Package couldn't be installed in " + pkg.codePath, e); 15260 } 15261 15262 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 15263 // Re installation failed. Restore old information 15264 // Remove new pkg information 15265 if (newPackage != null) { 15266 removeInstalledPackageLI(newPackage, true); 15267 } 15268 // Add back the old system package 15269 try { 15270 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 15271 } catch (PackageManagerException e) { 15272 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 15273 } 15274 15275 synchronized (mPackages) { 15276 if (disabledSystem) { 15277 enableSystemPackageLPw(deletedPackage); 15278 } 15279 15280 // Ensure the installer package name up to date 15281 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 15282 15283 // Update permissions for restored package 15284 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 15285 15286 mSettings.writeLPr(); 15287 } 15288 15289 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 15290 + " after failed upgrade"); 15291 } 15292 } 15293 15294 /** 15295 * Checks whether the parent or any of the child packages have a change shared 15296 * user. For a package to be a valid update the shred users of the parent and 15297 * the children should match. We may later support changing child shared users. 15298 * @param oldPkg The updated package. 15299 * @param newPkg The update package. 15300 * @return The shared user that change between the versions. 15301 */ 15302 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 15303 PackageParser.Package newPkg) { 15304 // Check parent shared user 15305 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 15306 return newPkg.packageName; 15307 } 15308 // Check child shared users 15309 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 15310 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 15311 for (int i = 0; i < newChildCount; i++) { 15312 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 15313 // If this child was present, did it have the same shared user? 15314 for (int j = 0; j < oldChildCount; j++) { 15315 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 15316 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 15317 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 15318 return newChildPkg.packageName; 15319 } 15320 } 15321 } 15322 return null; 15323 } 15324 15325 private void removeNativeBinariesLI(PackageSetting ps) { 15326 // Remove the lib path for the parent package 15327 if (ps != null) { 15328 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 15329 // Remove the lib path for the child packages 15330 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 15331 for (int i = 0; i < childCount; i++) { 15332 PackageSetting childPs = null; 15333 synchronized (mPackages) { 15334 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 15335 } 15336 if (childPs != null) { 15337 NativeLibraryHelper.removeNativeBinariesLI(childPs 15338 .legacyNativeLibraryPathString); 15339 } 15340 } 15341 } 15342 } 15343 15344 private void enableSystemPackageLPw(PackageParser.Package pkg) { 15345 // Enable the parent package 15346 mSettings.enableSystemPackageLPw(pkg.packageName); 15347 // Enable the child packages 15348 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15349 for (int i = 0; i < childCount; i++) { 15350 PackageParser.Package childPkg = pkg.childPackages.get(i); 15351 mSettings.enableSystemPackageLPw(childPkg.packageName); 15352 } 15353 } 15354 15355 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 15356 PackageParser.Package newPkg) { 15357 // Disable the parent package (parent always replaced) 15358 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 15359 // Disable the child packages 15360 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 15361 for (int i = 0; i < childCount; i++) { 15362 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 15363 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 15364 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 15365 } 15366 return disabled; 15367 } 15368 15369 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 15370 String installerPackageName) { 15371 // Enable the parent package 15372 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 15373 // Enable the child packages 15374 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15375 for (int i = 0; i < childCount; i++) { 15376 PackageParser.Package childPkg = pkg.childPackages.get(i); 15377 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 15378 } 15379 } 15380 15381 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 15382 // Collect all used permissions in the UID 15383 ArraySet<String> usedPermissions = new ArraySet<>(); 15384 final int packageCount = su.packages.size(); 15385 for (int i = 0; i < packageCount; i++) { 15386 PackageSetting ps = su.packages.valueAt(i); 15387 if (ps.pkg == null) { 15388 continue; 15389 } 15390 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 15391 for (int j = 0; j < requestedPermCount; j++) { 15392 String permission = ps.pkg.requestedPermissions.get(j); 15393 BasePermission bp = mSettings.mPermissions.get(permission); 15394 if (bp != null) { 15395 usedPermissions.add(permission); 15396 } 15397 } 15398 } 15399 15400 PermissionsState permissionsState = su.getPermissionsState(); 15401 // Prune install permissions 15402 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 15403 final int installPermCount = installPermStates.size(); 15404 for (int i = installPermCount - 1; i >= 0; i--) { 15405 PermissionState permissionState = installPermStates.get(i); 15406 if (!usedPermissions.contains(permissionState.getName())) { 15407 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 15408 if (bp != null) { 15409 permissionsState.revokeInstallPermission(bp); 15410 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 15411 PackageManager.MASK_PERMISSION_FLAGS, 0); 15412 } 15413 } 15414 } 15415 15416 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 15417 15418 // Prune runtime permissions 15419 for (int userId : allUserIds) { 15420 List<PermissionState> runtimePermStates = permissionsState 15421 .getRuntimePermissionStates(userId); 15422 final int runtimePermCount = runtimePermStates.size(); 15423 for (int i = runtimePermCount - 1; i >= 0; i--) { 15424 PermissionState permissionState = runtimePermStates.get(i); 15425 if (!usedPermissions.contains(permissionState.getName())) { 15426 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 15427 if (bp != null) { 15428 permissionsState.revokeRuntimePermission(bp, userId); 15429 permissionsState.updatePermissionFlags(bp, userId, 15430 PackageManager.MASK_PERMISSION_FLAGS, 0); 15431 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 15432 runtimePermissionChangedUserIds, userId); 15433 } 15434 } 15435 } 15436 } 15437 15438 return runtimePermissionChangedUserIds; 15439 } 15440 15441 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 15442 int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) { 15443 // Update the parent package setting 15444 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 15445 res, user, installReason); 15446 // Update the child packages setting 15447 final int childCount = (newPackage.childPackages != null) 15448 ? newPackage.childPackages.size() : 0; 15449 for (int i = 0; i < childCount; i++) { 15450 PackageParser.Package childPackage = newPackage.childPackages.get(i); 15451 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 15452 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 15453 childRes.origUsers, childRes, user, installReason); 15454 } 15455 } 15456 15457 private void updateSettingsInternalLI(PackageParser.Package newPackage, 15458 String installerPackageName, int[] allUsers, int[] installedForUsers, 15459 PackageInstalledInfo res, UserHandle user, int installReason) { 15460 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 15461 15462 String pkgName = newPackage.packageName; 15463 synchronized (mPackages) { 15464 //write settings. the installStatus will be incomplete at this stage. 15465 //note that the new package setting would have already been 15466 //added to mPackages. It hasn't been persisted yet. 15467 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 15468 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 15469 mSettings.writeLPr(); 15470 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15471 } 15472 15473 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 15474 synchronized (mPackages) { 15475 updatePermissionsLPw(newPackage.packageName, newPackage, 15476 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 15477 ? UPDATE_PERMISSIONS_ALL : 0)); 15478 // For system-bundled packages, we assume that installing an upgraded version 15479 // of the package implies that the user actually wants to run that new code, 15480 // so we enable the package. 15481 PackageSetting ps = mSettings.mPackages.get(pkgName); 15482 final int userId = user.getIdentifier(); 15483 if (ps != null) { 15484 if (isSystemApp(newPackage)) { 15485 if (DEBUG_INSTALL) { 15486 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 15487 } 15488 // Enable system package for requested users 15489 if (res.origUsers != null) { 15490 for (int origUserId : res.origUsers) { 15491 if (userId == UserHandle.USER_ALL || userId == origUserId) { 15492 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 15493 origUserId, installerPackageName); 15494 } 15495 } 15496 } 15497 // Also convey the prior install/uninstall state 15498 if (allUsers != null && installedForUsers != null) { 15499 for (int currentUserId : allUsers) { 15500 final boolean installed = ArrayUtils.contains( 15501 installedForUsers, currentUserId); 15502 if (DEBUG_INSTALL) { 15503 Slog.d(TAG, " user " + currentUserId + " => " + installed); 15504 } 15505 ps.setInstalled(installed, currentUserId); 15506 } 15507 // these install state changes will be persisted in the 15508 // upcoming call to mSettings.writeLPr(). 15509 } 15510 } 15511 // It's implied that when a user requests installation, they want the app to be 15512 // installed and enabled. 15513 if (userId != UserHandle.USER_ALL) { 15514 ps.setInstalled(true, userId); 15515 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 15516 } 15517 15518 // When replacing an existing package, preserve the original install reason for all 15519 // users that had the package installed before. 15520 final Set<Integer> previousUserIds = new ArraySet<>(); 15521 if (res.removedInfo != null && res.removedInfo.installReasons != null) { 15522 final int installReasonCount = res.removedInfo.installReasons.size(); 15523 for (int i = 0; i < installReasonCount; i++) { 15524 final int previousUserId = res.removedInfo.installReasons.keyAt(i); 15525 final int previousInstallReason = res.removedInfo.installReasons.valueAt(i); 15526 ps.setInstallReason(previousInstallReason, previousUserId); 15527 previousUserIds.add(previousUserId); 15528 } 15529 } 15530 15531 // Set install reason for users that are having the package newly installed. 15532 if (userId == UserHandle.USER_ALL) { 15533 for (int currentUserId : sUserManager.getUserIds()) { 15534 if (!previousUserIds.contains(currentUserId)) { 15535 ps.setInstallReason(installReason, currentUserId); 15536 } 15537 } 15538 } else if (!previousUserIds.contains(userId)) { 15539 ps.setInstallReason(installReason, userId); 15540 } 15541 } 15542 res.name = pkgName; 15543 res.uid = newPackage.applicationInfo.uid; 15544 res.pkg = newPackage; 15545 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 15546 mSettings.setInstallerPackageName(pkgName, installerPackageName); 15547 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15548 //to update install status 15549 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 15550 mSettings.writeLPr(); 15551 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15552 } 15553 15554 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15555 } 15556 15557 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 15558 try { 15559 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 15560 installPackageLI(args, res); 15561 } finally { 15562 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15563 } 15564 } 15565 15566 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 15567 final int installFlags = args.installFlags; 15568 final String installerPackageName = args.installerPackageName; 15569 final String volumeUuid = args.volumeUuid; 15570 final File tmpPackageFile = new File(args.getCodePath()); 15571 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 15572 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 15573 || (args.volumeUuid != null)); 15574 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 15575 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 15576 boolean replace = false; 15577 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 15578 if (args.move != null) { 15579 // moving a complete application; perform an initial scan on the new install location 15580 scanFlags |= SCAN_INITIAL; 15581 } 15582 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 15583 scanFlags |= SCAN_DONT_KILL_APP; 15584 } 15585 15586 // Result object to be returned 15587 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15588 15589 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 15590 15591 // Sanity check 15592 if (ephemeral && (forwardLocked || onExternal)) { 15593 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 15594 + " external=" + onExternal); 15595 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 15596 return; 15597 } 15598 15599 // Retrieve PackageSettings and parse package 15600 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 15601 | PackageParser.PARSE_ENFORCE_CODE 15602 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 15603 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 15604 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) 15605 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 15606 PackageParser pp = new PackageParser(); 15607 pp.setSeparateProcesses(mSeparateProcesses); 15608 pp.setDisplayMetrics(mMetrics); 15609 15610 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 15611 final PackageParser.Package pkg; 15612 try { 15613 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 15614 } catch (PackageParserException e) { 15615 res.setError("Failed parse during installPackageLI", e); 15616 return; 15617 } finally { 15618 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15619 } 15620 15621 // Ephemeral apps must have target SDK >= O. 15622 // TODO: Update conditional and error message when O gets locked down 15623 if (ephemeral && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) { 15624 res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID, 15625 "Ephemeral apps must have target SDK version of at least O"); 15626 return; 15627 } 15628 15629 // If we are installing a clustered package add results for the children 15630 if (pkg.childPackages != null) { 15631 synchronized (mPackages) { 15632 final int childCount = pkg.childPackages.size(); 15633 for (int i = 0; i < childCount; i++) { 15634 PackageParser.Package childPkg = pkg.childPackages.get(i); 15635 PackageInstalledInfo childRes = new PackageInstalledInfo(); 15636 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15637 childRes.pkg = childPkg; 15638 childRes.name = childPkg.packageName; 15639 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 15640 if (childPs != null) { 15641 childRes.origUsers = childPs.queryInstalledUsers( 15642 sUserManager.getUserIds(), true); 15643 } 15644 if ((mPackages.containsKey(childPkg.packageName))) { 15645 childRes.removedInfo = new PackageRemovedInfo(); 15646 childRes.removedInfo.removedPackage = childPkg.packageName; 15647 } 15648 if (res.addedChildPackages == null) { 15649 res.addedChildPackages = new ArrayMap<>(); 15650 } 15651 res.addedChildPackages.put(childPkg.packageName, childRes); 15652 } 15653 } 15654 } 15655 15656 // If package doesn't declare API override, mark that we have an install 15657 // time CPU ABI override. 15658 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 15659 pkg.cpuAbiOverride = args.abiOverride; 15660 } 15661 15662 String pkgName = res.name = pkg.packageName; 15663 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 15664 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 15665 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 15666 return; 15667 } 15668 } 15669 15670 try { 15671 // either use what we've been given or parse directly from the APK 15672 if (args.certificates != null) { 15673 try { 15674 PackageParser.populateCertificates(pkg, args.certificates); 15675 } catch (PackageParserException e) { 15676 // there was something wrong with the certificates we were given; 15677 // try to pull them from the APK 15678 PackageParser.collectCertificates(pkg, parseFlags); 15679 } 15680 } else { 15681 PackageParser.collectCertificates(pkg, parseFlags); 15682 } 15683 } catch (PackageParserException e) { 15684 res.setError("Failed collect during installPackageLI", e); 15685 return; 15686 } 15687 15688 // Get rid of all references to package scan path via parser. 15689 pp = null; 15690 String oldCodePath = null; 15691 boolean systemApp = false; 15692 synchronized (mPackages) { 15693 // Check if installing already existing package 15694 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 15695 String oldName = mSettings.getRenamedPackageLPr(pkgName); 15696 if (pkg.mOriginalPackages != null 15697 && pkg.mOriginalPackages.contains(oldName) 15698 && mPackages.containsKey(oldName)) { 15699 // This package is derived from an original package, 15700 // and this device has been updating from that original 15701 // name. We must continue using the original name, so 15702 // rename the new package here. 15703 pkg.setPackageName(oldName); 15704 pkgName = pkg.packageName; 15705 replace = true; 15706 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 15707 + oldName + " pkgName=" + pkgName); 15708 } else if (mPackages.containsKey(pkgName)) { 15709 // This package, under its official name, already exists 15710 // on the device; we should replace it. 15711 replace = true; 15712 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 15713 } 15714 15715 // Child packages are installed through the parent package 15716 if (pkg.parentPackage != null) { 15717 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15718 "Package " + pkg.packageName + " is child of package " 15719 + pkg.parentPackage.parentPackage + ". Child packages " 15720 + "can be updated only through the parent package."); 15721 return; 15722 } 15723 15724 if (replace) { 15725 // Prevent apps opting out from runtime permissions 15726 PackageParser.Package oldPackage = mPackages.get(pkgName); 15727 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 15728 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 15729 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 15730 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 15731 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 15732 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 15733 + " doesn't support runtime permissions but the old" 15734 + " target SDK " + oldTargetSdk + " does."); 15735 return; 15736 } 15737 15738 // Prevent installing of child packages 15739 if (oldPackage.parentPackage != null) { 15740 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15741 "Package " + pkg.packageName + " is child of package " 15742 + oldPackage.parentPackage + ". Child packages " 15743 + "can be updated only through the parent package."); 15744 return; 15745 } 15746 } 15747 } 15748 15749 PackageSetting ps = mSettings.mPackages.get(pkgName); 15750 if (ps != null) { 15751 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 15752 15753 // Quick sanity check that we're signed correctly if updating; 15754 // we'll check this again later when scanning, but we want to 15755 // bail early here before tripping over redefined permissions. 15756 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 15757 if (!checkUpgradeKeySetLP(ps, pkg)) { 15758 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 15759 + pkg.packageName + " upgrade keys do not match the " 15760 + "previously installed version"); 15761 return; 15762 } 15763 } else { 15764 try { 15765 verifySignaturesLP(ps, pkg); 15766 } catch (PackageManagerException e) { 15767 res.setError(e.error, e.getMessage()); 15768 return; 15769 } 15770 } 15771 15772 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 15773 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 15774 systemApp = (ps.pkg.applicationInfo.flags & 15775 ApplicationInfo.FLAG_SYSTEM) != 0; 15776 } 15777 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15778 } 15779 15780 // Check whether the newly-scanned package wants to define an already-defined perm 15781 int N = pkg.permissions.size(); 15782 for (int i = N-1; i >= 0; i--) { 15783 PackageParser.Permission perm = pkg.permissions.get(i); 15784 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 15785 if (bp != null) { 15786 // If the defining package is signed with our cert, it's okay. This 15787 // also includes the "updating the same package" case, of course. 15788 // "updating same package" could also involve key-rotation. 15789 final boolean sigsOk; 15790 if (bp.sourcePackage.equals(pkg.packageName) 15791 && (bp.packageSetting instanceof PackageSetting) 15792 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 15793 scanFlags))) { 15794 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 15795 } else { 15796 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 15797 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 15798 } 15799 if (!sigsOk) { 15800 // If the owning package is the system itself, we log but allow 15801 // install to proceed; we fail the install on all other permission 15802 // redefinitions. 15803 if (!bp.sourcePackage.equals("android")) { 15804 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 15805 + pkg.packageName + " attempting to redeclare permission " 15806 + perm.info.name + " already owned by " + bp.sourcePackage); 15807 res.origPermission = perm.info.name; 15808 res.origPackage = bp.sourcePackage; 15809 return; 15810 } else { 15811 Slog.w(TAG, "Package " + pkg.packageName 15812 + " attempting to redeclare system permission " 15813 + perm.info.name + "; ignoring new declaration"); 15814 pkg.permissions.remove(i); 15815 } 15816 } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { 15817 // Prevent apps to change protection level to dangerous from any other 15818 // type as this would allow a privilege escalation where an app adds a 15819 // normal/signature permission in other app's group and later redefines 15820 // it as dangerous leading to the group auto-grant. 15821 if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) 15822 == PermissionInfo.PROTECTION_DANGEROUS) { 15823 if (bp != null && !bp.isRuntime()) { 15824 Slog.w(TAG, "Package " + pkg.packageName + " trying to change a " 15825 + "non-runtime permission " + perm.info.name 15826 + " to runtime; keeping old protection level"); 15827 perm.info.protectionLevel = bp.protectionLevel; 15828 } 15829 } 15830 } 15831 } 15832 } 15833 } 15834 15835 if (systemApp) { 15836 if (onExternal) { 15837 // Abort update; system app can't be replaced with app on sdcard 15838 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 15839 "Cannot install updates to system apps on sdcard"); 15840 return; 15841 } else if (ephemeral) { 15842 // Abort update; system app can't be replaced with an ephemeral app 15843 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 15844 "Cannot update a system app with an ephemeral app"); 15845 return; 15846 } 15847 } 15848 15849 if (args.move != null) { 15850 // We did an in-place move, so dex is ready to roll 15851 scanFlags |= SCAN_NO_DEX; 15852 scanFlags |= SCAN_MOVE; 15853 15854 synchronized (mPackages) { 15855 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15856 if (ps == null) { 15857 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 15858 "Missing settings for moved package " + pkgName); 15859 } 15860 15861 // We moved the entire application as-is, so bring over the 15862 // previously derived ABI information. 15863 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 15864 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 15865 } 15866 15867 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 15868 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 15869 scanFlags |= SCAN_NO_DEX; 15870 15871 try { 15872 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 15873 args.abiOverride : pkg.cpuAbiOverride); 15874 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 15875 true /*extractLibs*/, mAppLib32InstallDir); 15876 } catch (PackageManagerException pme) { 15877 Slog.e(TAG, "Error deriving application ABI", pme); 15878 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 15879 return; 15880 } 15881 15882 // Shared libraries for the package need to be updated. 15883 synchronized (mPackages) { 15884 try { 15885 updateSharedLibrariesLPr(pkg, null); 15886 } catch (PackageManagerException e) { 15887 Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage()); 15888 } 15889 } 15890 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 15891 // Do not run PackageDexOptimizer through the local performDexOpt 15892 // method because `pkg` may not be in `mPackages` yet. 15893 // 15894 // Also, don't fail application installs if the dexopt step fails. 15895 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 15896 null /* instructionSets */, false /* checkProfiles */, 15897 getCompilerFilterForReason(REASON_INSTALL), 15898 getOrCreateCompilerPackageStats(pkg)); 15899 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15900 15901 // Notify BackgroundDexOptService that the package has been changed. 15902 // If this is an update of a package which used to fail to compile, 15903 // BDOS will remove it from its blacklist. 15904 BackgroundDexOptService.notifyPackageChanged(pkg.packageName); 15905 } 15906 15907 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 15908 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 15909 return; 15910 } 15911 15912 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 15913 15914 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 15915 "installPackageLI")) { 15916 if (replace) { 15917 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 15918 installerPackageName, res, args.installReason); 15919 } else { 15920 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 15921 args.user, installerPackageName, volumeUuid, res, args.installReason); 15922 } 15923 } 15924 synchronized (mPackages) { 15925 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15926 if (ps != null) { 15927 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15928 } 15929 15930 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15931 for (int i = 0; i < childCount; i++) { 15932 PackageParser.Package childPkg = pkg.childPackages.get(i); 15933 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15934 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 15935 if (childPs != null) { 15936 childRes.newUsers = childPs.queryInstalledUsers( 15937 sUserManager.getUserIds(), true); 15938 } 15939 } 15940 } 15941 } 15942 15943 private void startIntentFilterVerifications(int userId, boolean replacing, 15944 PackageParser.Package pkg) { 15945 if (mIntentFilterVerifierComponent == null) { 15946 Slog.w(TAG, "No IntentFilter verification will not be done as " 15947 + "there is no IntentFilterVerifier available!"); 15948 return; 15949 } 15950 15951 final int verifierUid = getPackageUid( 15952 mIntentFilterVerifierComponent.getPackageName(), 15953 MATCH_DEBUG_TRIAGED_MISSING, 15954 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 15955 15956 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15957 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 15958 mHandler.sendMessage(msg); 15959 15960 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15961 for (int i = 0; i < childCount; i++) { 15962 PackageParser.Package childPkg = pkg.childPackages.get(i); 15963 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15964 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 15965 mHandler.sendMessage(msg); 15966 } 15967 } 15968 15969 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 15970 PackageParser.Package pkg) { 15971 int size = pkg.activities.size(); 15972 if (size == 0) { 15973 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15974 "No activity, so no need to verify any IntentFilter!"); 15975 return; 15976 } 15977 15978 final boolean hasDomainURLs = hasDomainURLs(pkg); 15979 if (!hasDomainURLs) { 15980 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15981 "No domain URLs, so no need to verify any IntentFilter!"); 15982 return; 15983 } 15984 15985 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 15986 + " if any IntentFilter from the " + size 15987 + " Activities needs verification ..."); 15988 15989 int count = 0; 15990 final String packageName = pkg.packageName; 15991 15992 synchronized (mPackages) { 15993 // If this is a new install and we see that we've already run verification for this 15994 // package, we have nothing to do: it means the state was restored from backup. 15995 if (!replacing) { 15996 IntentFilterVerificationInfo ivi = 15997 mSettings.getIntentFilterVerificationLPr(packageName); 15998 if (ivi != null) { 15999 if (DEBUG_DOMAIN_VERIFICATION) { 16000 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 16001 + ivi.getStatusString()); 16002 } 16003 return; 16004 } 16005 } 16006 16007 // If any filters need to be verified, then all need to be. 16008 boolean needToVerify = false; 16009 for (PackageParser.Activity a : pkg.activities) { 16010 for (ActivityIntentInfo filter : a.intents) { 16011 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 16012 if (DEBUG_DOMAIN_VERIFICATION) { 16013 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 16014 } 16015 needToVerify = true; 16016 break; 16017 } 16018 } 16019 } 16020 16021 if (needToVerify) { 16022 final int verificationId = mIntentFilterVerificationToken++; 16023 for (PackageParser.Activity a : pkg.activities) { 16024 for (ActivityIntentInfo filter : a.intents) { 16025 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 16026 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 16027 "Verification needed for IntentFilter:" + filter.toString()); 16028 mIntentFilterVerifier.addOneIntentFilterVerification( 16029 verifierUid, userId, verificationId, filter, packageName); 16030 count++; 16031 } 16032 } 16033 } 16034 } 16035 } 16036 16037 if (count > 0) { 16038 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 16039 + " IntentFilter verification" + (count > 1 ? "s" : "") 16040 + " for userId:" + userId); 16041 mIntentFilterVerifier.startVerifications(userId); 16042 } else { 16043 if (DEBUG_DOMAIN_VERIFICATION) { 16044 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 16045 } 16046 } 16047 } 16048 16049 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 16050 final ComponentName cn = filter.activity.getComponentName(); 16051 final String packageName = cn.getPackageName(); 16052 16053 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 16054 packageName); 16055 if (ivi == null) { 16056 return true; 16057 } 16058 int status = ivi.getStatus(); 16059 switch (status) { 16060 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 16061 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 16062 return true; 16063 16064 default: 16065 // Nothing to do 16066 return false; 16067 } 16068 } 16069 16070 private static boolean isMultiArch(ApplicationInfo info) { 16071 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 16072 } 16073 16074 private static boolean isExternal(PackageParser.Package pkg) { 16075 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 16076 } 16077 16078 private static boolean isExternal(PackageSetting ps) { 16079 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 16080 } 16081 16082 private static boolean isEphemeral(PackageParser.Package pkg) { 16083 return pkg.applicationInfo.isEphemeralApp(); 16084 } 16085 16086 private static boolean isEphemeral(PackageSetting ps) { 16087 return ps.pkg != null && isEphemeral(ps.pkg); 16088 } 16089 16090 private static boolean isSystemApp(PackageParser.Package pkg) { 16091 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 16092 } 16093 16094 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 16095 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 16096 } 16097 16098 private static boolean hasDomainURLs(PackageParser.Package pkg) { 16099 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 16100 } 16101 16102 private static boolean isSystemApp(PackageSetting ps) { 16103 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 16104 } 16105 16106 private static boolean isUpdatedSystemApp(PackageSetting ps) { 16107 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 16108 } 16109 16110 private int packageFlagsToInstallFlags(PackageSetting ps) { 16111 int installFlags = 0; 16112 if (isEphemeral(ps)) { 16113 installFlags |= PackageManager.INSTALL_EPHEMERAL; 16114 } 16115 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 16116 // This existing package was an external ASEC install when we have 16117 // the external flag without a UUID 16118 installFlags |= PackageManager.INSTALL_EXTERNAL; 16119 } 16120 if (ps.isForwardLocked()) { 16121 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 16122 } 16123 return installFlags; 16124 } 16125 16126 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 16127 if (isExternal(pkg)) { 16128 if (TextUtils.isEmpty(pkg.volumeUuid)) { 16129 return StorageManager.UUID_PRIMARY_PHYSICAL; 16130 } else { 16131 return pkg.volumeUuid; 16132 } 16133 } else { 16134 return StorageManager.UUID_PRIVATE_INTERNAL; 16135 } 16136 } 16137 16138 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 16139 if (isExternal(pkg)) { 16140 if (TextUtils.isEmpty(pkg.volumeUuid)) { 16141 return mSettings.getExternalVersion(); 16142 } else { 16143 return mSettings.findOrCreateVersion(pkg.volumeUuid); 16144 } 16145 } else { 16146 return mSettings.getInternalVersion(); 16147 } 16148 } 16149 16150 private void deleteTempPackageFiles() { 16151 final FilenameFilter filter = new FilenameFilter() { 16152 public boolean accept(File dir, String name) { 16153 return name.startsWith("vmdl") && name.endsWith(".tmp"); 16154 } 16155 }; 16156 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 16157 file.delete(); 16158 } 16159 } 16160 16161 @Override 16162 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 16163 int flags) { 16164 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 16165 flags); 16166 } 16167 16168 @Override 16169 public void deletePackage(final String packageName, 16170 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 16171 mContext.enforceCallingOrSelfPermission( 16172 android.Manifest.permission.DELETE_PACKAGES, null); 16173 Preconditions.checkNotNull(packageName); 16174 Preconditions.checkNotNull(observer); 16175 final int uid = Binder.getCallingUid(); 16176 if (!isOrphaned(packageName) 16177 && !isCallerAllowedToSilentlyUninstall(uid, packageName)) { 16178 try { 16179 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 16180 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 16181 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 16182 observer.onUserActionRequired(intent); 16183 } catch (RemoteException re) { 16184 } 16185 return; 16186 } 16187 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 16188 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 16189 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 16190 mContext.enforceCallingOrSelfPermission( 16191 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 16192 "deletePackage for user " + userId); 16193 } 16194 16195 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 16196 try { 16197 observer.onPackageDeleted(packageName, 16198 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 16199 } catch (RemoteException re) { 16200 } 16201 return; 16202 } 16203 16204 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 16205 try { 16206 observer.onPackageDeleted(packageName, 16207 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 16208 } catch (RemoteException re) { 16209 } 16210 return; 16211 } 16212 16213 if (DEBUG_REMOVE) { 16214 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 16215 + " deleteAllUsers: " + deleteAllUsers ); 16216 } 16217 // Queue up an async operation since the package deletion may take a little while. 16218 mHandler.post(new Runnable() { 16219 public void run() { 16220 mHandler.removeCallbacks(this); 16221 int returnCode; 16222 if (!deleteAllUsers) { 16223 returnCode = deletePackageX(packageName, userId, deleteFlags); 16224 } else { 16225 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 16226 // If nobody is blocking uninstall, proceed with delete for all users 16227 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 16228 returnCode = deletePackageX(packageName, userId, deleteFlags); 16229 } else { 16230 // Otherwise uninstall individually for users with blockUninstalls=false 16231 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 16232 for (int userId : users) { 16233 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 16234 returnCode = deletePackageX(packageName, userId, userFlags); 16235 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 16236 Slog.w(TAG, "Package delete failed for user " + userId 16237 + ", returnCode " + returnCode); 16238 } 16239 } 16240 } 16241 // The app has only been marked uninstalled for certain users. 16242 // We still need to report that delete was blocked 16243 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 16244 } 16245 } 16246 try { 16247 observer.onPackageDeleted(packageName, returnCode, null); 16248 } catch (RemoteException e) { 16249 Log.i(TAG, "Observer no longer exists."); 16250 } //end catch 16251 } //end run 16252 }); 16253 } 16254 16255 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) { 16256 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID 16257 || callingUid == Process.SYSTEM_UID) { 16258 return true; 16259 } 16260 final int callingUserId = UserHandle.getUserId(callingUid); 16261 // If the caller installed the pkgName, then allow it to silently uninstall. 16262 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) { 16263 return true; 16264 } 16265 16266 // Allow package verifier to silently uninstall. 16267 if (mRequiredVerifierPackage != null && 16268 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) { 16269 return true; 16270 } 16271 16272 // Allow package uninstaller to silently uninstall. 16273 if (mRequiredUninstallerPackage != null && 16274 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { 16275 return true; 16276 } 16277 16278 // Allow storage manager to silently uninstall. 16279 if (mStorageManagerPackage != null && 16280 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { 16281 return true; 16282 } 16283 return false; 16284 } 16285 16286 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 16287 int[] result = EMPTY_INT_ARRAY; 16288 for (int userId : userIds) { 16289 if (getBlockUninstallForUser(packageName, userId)) { 16290 result = ArrayUtils.appendInt(result, userId); 16291 } 16292 } 16293 return result; 16294 } 16295 16296 @Override 16297 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 16298 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 16299 } 16300 16301 private boolean isPackageDeviceAdmin(String packageName, int userId) { 16302 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 16303 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 16304 try { 16305 if (dpm != null) { 16306 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 16307 /* callingUserOnly =*/ false); 16308 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 16309 : deviceOwnerComponentName.getPackageName(); 16310 // Does the package contains the device owner? 16311 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 16312 // this check is probably not needed, since DO should be registered as a device 16313 // admin on some user too. (Original bug for this: b/17657954) 16314 if (packageName.equals(deviceOwnerPackageName)) { 16315 return true; 16316 } 16317 // Does it contain a device admin for any user? 16318 int[] users; 16319 if (userId == UserHandle.USER_ALL) { 16320 users = sUserManager.getUserIds(); 16321 } else { 16322 users = new int[]{userId}; 16323 } 16324 for (int i = 0; i < users.length; ++i) { 16325 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 16326 return true; 16327 } 16328 } 16329 } 16330 } catch (RemoteException e) { 16331 } 16332 return false; 16333 } 16334 16335 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 16336 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 16337 } 16338 16339 /** 16340 * This method is an internal method that could be get invoked either 16341 * to delete an installed package or to clean up a failed installation. 16342 * After deleting an installed package, a broadcast is sent to notify any 16343 * listeners that the package has been removed. For cleaning up a failed 16344 * installation, the broadcast is not necessary since the package's 16345 * installation wouldn't have sent the initial broadcast either 16346 * The key steps in deleting a package are 16347 * deleting the package information in internal structures like mPackages, 16348 * deleting the packages base directories through installd 16349 * updating mSettings to reflect current status 16350 * persisting settings for later use 16351 * sending a broadcast if necessary 16352 */ 16353 private int deletePackageX(String packageName, int userId, int deleteFlags) { 16354 final PackageRemovedInfo info = new PackageRemovedInfo(); 16355 final boolean res; 16356 16357 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 16358 ? UserHandle.USER_ALL : userId; 16359 16360 if (isPackageDeviceAdmin(packageName, removeUser)) { 16361 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 16362 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 16363 } 16364 16365 PackageSetting uninstalledPs = null; 16366 16367 // for the uninstall-updates case and restricted profiles, remember the per- 16368 // user handle installed state 16369 int[] allUsers; 16370 synchronized (mPackages) { 16371 uninstalledPs = mSettings.mPackages.get(packageName); 16372 if (uninstalledPs == null) { 16373 Slog.w(TAG, "Not removing non-existent package " + packageName); 16374 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 16375 } 16376 allUsers = sUserManager.getUserIds(); 16377 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 16378 } 16379 16380 final int freezeUser; 16381 if (isUpdatedSystemApp(uninstalledPs) 16382 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 16383 // We're downgrading a system app, which will apply to all users, so 16384 // freeze them all during the downgrade 16385 freezeUser = UserHandle.USER_ALL; 16386 } else { 16387 freezeUser = removeUser; 16388 } 16389 16390 synchronized (mInstallLock) { 16391 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 16392 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 16393 deleteFlags, "deletePackageX")) { 16394 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 16395 deleteFlags | REMOVE_CHATTY, info, true, null); 16396 } 16397 synchronized (mPackages) { 16398 if (res) { 16399 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 16400 } 16401 } 16402 } 16403 16404 if (res) { 16405 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 16406 info.sendPackageRemovedBroadcasts(killApp); 16407 info.sendSystemPackageUpdatedBroadcasts(); 16408 info.sendSystemPackageAppearedBroadcasts(); 16409 } 16410 // Force a gc here. 16411 Runtime.getRuntime().gc(); 16412 // Delete the resources here after sending the broadcast to let 16413 // other processes clean up before deleting resources. 16414 if (info.args != null) { 16415 synchronized (mInstallLock) { 16416 info.args.doPostDeleteLI(true); 16417 } 16418 } 16419 16420 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 16421 } 16422 16423 class PackageRemovedInfo { 16424 String removedPackage; 16425 int uid = -1; 16426 int removedAppId = -1; 16427 int[] origUsers; 16428 int[] removedUsers = null; 16429 SparseArray<Integer> installReasons; 16430 boolean isRemovedPackageSystemUpdate = false; 16431 boolean isUpdate; 16432 boolean dataRemoved; 16433 boolean removedForAllUsers; 16434 // Clean up resources deleted packages. 16435 InstallArgs args = null; 16436 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 16437 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 16438 16439 void sendPackageRemovedBroadcasts(boolean killApp) { 16440 sendPackageRemovedBroadcastInternal(killApp); 16441 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 16442 for (int i = 0; i < childCount; i++) { 16443 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 16444 childInfo.sendPackageRemovedBroadcastInternal(killApp); 16445 } 16446 } 16447 16448 void sendSystemPackageUpdatedBroadcasts() { 16449 if (isRemovedPackageSystemUpdate) { 16450 sendSystemPackageUpdatedBroadcastsInternal(); 16451 final int childCount = (removedChildPackages != null) 16452 ? removedChildPackages.size() : 0; 16453 for (int i = 0; i < childCount; i++) { 16454 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 16455 if (childInfo.isRemovedPackageSystemUpdate) { 16456 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 16457 } 16458 } 16459 } 16460 } 16461 16462 void sendSystemPackageAppearedBroadcasts() { 16463 final int packageCount = (appearedChildPackages != null) 16464 ? appearedChildPackages.size() : 0; 16465 for (int i = 0; i < packageCount; i++) { 16466 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 16467 sendPackageAddedForNewUsers(installedInfo.name, true, 16468 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers); 16469 } 16470 } 16471 16472 private void sendSystemPackageUpdatedBroadcastsInternal() { 16473 Bundle extras = new Bundle(2); 16474 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 16475 extras.putBoolean(Intent.EXTRA_REPLACING, true); 16476 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 16477 extras, 0, null, null, null); 16478 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 16479 extras, 0, null, null, null); 16480 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 16481 null, 0, removedPackage, null, null); 16482 } 16483 16484 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 16485 Bundle extras = new Bundle(2); 16486 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 16487 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 16488 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 16489 if (isUpdate || isRemovedPackageSystemUpdate) { 16490 extras.putBoolean(Intent.EXTRA_REPLACING, true); 16491 } 16492 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 16493 if (removedPackage != null) { 16494 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 16495 extras, 0, null, null, removedUsers); 16496 if (dataRemoved && !isRemovedPackageSystemUpdate) { 16497 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 16498 removedPackage, extras, 0, null, null, removedUsers); 16499 } 16500 } 16501 if (removedAppId >= 0) { 16502 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 16503 removedUsers); 16504 } 16505 } 16506 } 16507 16508 /* 16509 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 16510 * flag is not set, the data directory is removed as well. 16511 * make sure this flag is set for partially installed apps. If not its meaningless to 16512 * delete a partially installed application. 16513 */ 16514 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 16515 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 16516 String packageName = ps.name; 16517 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 16518 // Retrieve object to delete permissions for shared user later on 16519 final PackageParser.Package deletedPkg; 16520 final PackageSetting deletedPs; 16521 // reader 16522 synchronized (mPackages) { 16523 deletedPkg = mPackages.get(packageName); 16524 deletedPs = mSettings.mPackages.get(packageName); 16525 if (outInfo != null) { 16526 outInfo.removedPackage = packageName; 16527 outInfo.removedUsers = deletedPs != null 16528 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 16529 : null; 16530 } 16531 } 16532 16533 removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); 16534 16535 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 16536 final PackageParser.Package resolvedPkg; 16537 if (deletedPkg != null) { 16538 resolvedPkg = deletedPkg; 16539 } else { 16540 // We don't have a parsed package when it lives on an ejected 16541 // adopted storage device, so fake something together 16542 resolvedPkg = new PackageParser.Package(ps.name); 16543 resolvedPkg.setVolumeUuid(ps.volumeUuid); 16544 } 16545 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 16546 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16547 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 16548 if (outInfo != null) { 16549 outInfo.dataRemoved = true; 16550 } 16551 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 16552 } 16553 16554 // writer 16555 synchronized (mPackages) { 16556 if (deletedPs != null) { 16557 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 16558 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 16559 clearDefaultBrowserIfNeeded(packageName); 16560 if (outInfo != null) { 16561 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 16562 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 16563 } 16564 updatePermissionsLPw(deletedPs.name, null, 0); 16565 if (deletedPs.sharedUser != null) { 16566 // Remove permissions associated with package. Since runtime 16567 // permissions are per user we have to kill the removed package 16568 // or packages running under the shared user of the removed 16569 // package if revoking the permissions requested only by the removed 16570 // package is successful and this causes a change in gids. 16571 for (int userId : UserManagerService.getInstance().getUserIds()) { 16572 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 16573 userId); 16574 if (userIdToKill == UserHandle.USER_ALL 16575 || userIdToKill >= UserHandle.USER_SYSTEM) { 16576 // If gids changed for this user, kill all affected packages. 16577 mHandler.post(new Runnable() { 16578 @Override 16579 public void run() { 16580 // This has to happen with no lock held. 16581 killApplication(deletedPs.name, deletedPs.appId, 16582 KILL_APP_REASON_GIDS_CHANGED); 16583 } 16584 }); 16585 break; 16586 } 16587 } 16588 } 16589 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 16590 } 16591 // make sure to preserve per-user disabled state if this removal was just 16592 // a downgrade of a system app to the factory package 16593 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 16594 if (DEBUG_REMOVE) { 16595 Slog.d(TAG, "Propagating install state across downgrade"); 16596 } 16597 for (int userId : allUserHandles) { 16598 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 16599 if (DEBUG_REMOVE) { 16600 Slog.d(TAG, " user " + userId + " => " + installed); 16601 } 16602 ps.setInstalled(installed, userId); 16603 } 16604 } 16605 } 16606 // can downgrade to reader 16607 if (writeSettings) { 16608 // Save settings now 16609 mSettings.writeLPr(); 16610 } 16611 } 16612 if (outInfo != null) { 16613 // A user ID was deleted here. Go through all users and remove it 16614 // from KeyStore. 16615 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 16616 } 16617 } 16618 16619 static boolean locationIsPrivileged(File path) { 16620 try { 16621 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 16622 .getCanonicalPath(); 16623 return path.getCanonicalPath().startsWith(privilegedAppDir); 16624 } catch (IOException e) { 16625 Slog.e(TAG, "Unable to access code path " + path); 16626 } 16627 return false; 16628 } 16629 16630 /* 16631 * Tries to delete system package. 16632 */ 16633 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 16634 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 16635 boolean writeSettings) { 16636 if (deletedPs.parentPackageName != null) { 16637 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 16638 return false; 16639 } 16640 16641 final boolean applyUserRestrictions 16642 = (allUserHandles != null) && (outInfo.origUsers != null); 16643 final PackageSetting disabledPs; 16644 // Confirm if the system package has been updated 16645 // An updated system app can be deleted. This will also have to restore 16646 // the system pkg from system partition 16647 // reader 16648 synchronized (mPackages) { 16649 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 16650 } 16651 16652 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 16653 + " disabledPs=" + disabledPs); 16654 16655 if (disabledPs == null) { 16656 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 16657 return false; 16658 } else if (DEBUG_REMOVE) { 16659 Slog.d(TAG, "Deleting system pkg from data partition"); 16660 } 16661 16662 if (DEBUG_REMOVE) { 16663 if (applyUserRestrictions) { 16664 Slog.d(TAG, "Remembering install states:"); 16665 for (int userId : allUserHandles) { 16666 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 16667 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 16668 } 16669 } 16670 } 16671 16672 // Delete the updated package 16673 outInfo.isRemovedPackageSystemUpdate = true; 16674 if (outInfo.removedChildPackages != null) { 16675 final int childCount = (deletedPs.childPackageNames != null) 16676 ? deletedPs.childPackageNames.size() : 0; 16677 for (int i = 0; i < childCount; i++) { 16678 String childPackageName = deletedPs.childPackageNames.get(i); 16679 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 16680 .contains(childPackageName)) { 16681 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16682 childPackageName); 16683 if (childInfo != null) { 16684 childInfo.isRemovedPackageSystemUpdate = true; 16685 } 16686 } 16687 } 16688 } 16689 16690 if (disabledPs.versionCode < deletedPs.versionCode) { 16691 // Delete data for downgrades 16692 flags &= ~PackageManager.DELETE_KEEP_DATA; 16693 } else { 16694 // Preserve data by setting flag 16695 flags |= PackageManager.DELETE_KEEP_DATA; 16696 } 16697 16698 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 16699 outInfo, writeSettings, disabledPs.pkg); 16700 if (!ret) { 16701 return false; 16702 } 16703 16704 // writer 16705 synchronized (mPackages) { 16706 // Reinstate the old system package 16707 enableSystemPackageLPw(disabledPs.pkg); 16708 // Remove any native libraries from the upgraded package. 16709 removeNativeBinariesLI(deletedPs); 16710 } 16711 16712 // Install the system package 16713 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 16714 int parseFlags = mDefParseFlags 16715 | PackageParser.PARSE_MUST_BE_APK 16716 | PackageParser.PARSE_IS_SYSTEM 16717 | PackageParser.PARSE_IS_SYSTEM_DIR; 16718 if (locationIsPrivileged(disabledPs.codePath)) { 16719 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 16720 } 16721 16722 final PackageParser.Package newPkg; 16723 try { 16724 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */, 16725 0 /* currentTime */, null); 16726 } catch (PackageManagerException e) { 16727 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 16728 + e.getMessage()); 16729 return false; 16730 } 16731 try { 16732 // update shared libraries for the newly re-installed system package 16733 updateSharedLibrariesLPr(newPkg, null); 16734 } catch (PackageManagerException e) { 16735 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 16736 } 16737 16738 prepareAppDataAfterInstallLIF(newPkg); 16739 16740 // writer 16741 synchronized (mPackages) { 16742 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 16743 16744 // Propagate the permissions state as we do not want to drop on the floor 16745 // runtime permissions. The update permissions method below will take 16746 // care of removing obsolete permissions and grant install permissions. 16747 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 16748 updatePermissionsLPw(newPkg.packageName, newPkg, 16749 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 16750 16751 if (applyUserRestrictions) { 16752 if (DEBUG_REMOVE) { 16753 Slog.d(TAG, "Propagating install state across reinstall"); 16754 } 16755 for (int userId : allUserHandles) { 16756 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 16757 if (DEBUG_REMOVE) { 16758 Slog.d(TAG, " user " + userId + " => " + installed); 16759 } 16760 ps.setInstalled(installed, userId); 16761 16762 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16763 } 16764 // Regardless of writeSettings we need to ensure that this restriction 16765 // state propagation is persisted 16766 mSettings.writeAllUsersPackageRestrictionsLPr(); 16767 } 16768 // can downgrade to reader here 16769 if (writeSettings) { 16770 mSettings.writeLPr(); 16771 } 16772 } 16773 return true; 16774 } 16775 16776 private boolean deleteInstalledPackageLIF(PackageSetting ps, 16777 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 16778 PackageRemovedInfo outInfo, boolean writeSettings, 16779 PackageParser.Package replacingPackage) { 16780 synchronized (mPackages) { 16781 if (outInfo != null) { 16782 outInfo.uid = ps.appId; 16783 } 16784 16785 if (outInfo != null && outInfo.removedChildPackages != null) { 16786 final int childCount = (ps.childPackageNames != null) 16787 ? ps.childPackageNames.size() : 0; 16788 for (int i = 0; i < childCount; i++) { 16789 String childPackageName = ps.childPackageNames.get(i); 16790 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 16791 if (childPs == null) { 16792 return false; 16793 } 16794 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16795 childPackageName); 16796 if (childInfo != null) { 16797 childInfo.uid = childPs.appId; 16798 } 16799 } 16800 } 16801 } 16802 16803 // Delete package data from internal structures and also remove data if flag is set 16804 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 16805 16806 // Delete the child packages data 16807 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 16808 for (int i = 0; i < childCount; i++) { 16809 PackageSetting childPs; 16810 synchronized (mPackages) { 16811 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 16812 } 16813 if (childPs != null) { 16814 PackageRemovedInfo childOutInfo = (outInfo != null 16815 && outInfo.removedChildPackages != null) 16816 ? outInfo.removedChildPackages.get(childPs.name) : null; 16817 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 16818 && (replacingPackage != null 16819 && !replacingPackage.hasChildPackage(childPs.name)) 16820 ? flags & ~DELETE_KEEP_DATA : flags; 16821 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 16822 deleteFlags, writeSettings); 16823 } 16824 } 16825 16826 // Delete application code and resources only for parent packages 16827 if (ps.parentPackageName == null) { 16828 if (deleteCodeAndResources && (outInfo != null)) { 16829 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 16830 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 16831 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 16832 } 16833 } 16834 16835 return true; 16836 } 16837 16838 @Override 16839 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 16840 int userId) { 16841 mContext.enforceCallingOrSelfPermission( 16842 android.Manifest.permission.DELETE_PACKAGES, null); 16843 synchronized (mPackages) { 16844 PackageSetting ps = mSettings.mPackages.get(packageName); 16845 if (ps == null) { 16846 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 16847 return false; 16848 } 16849 if (!ps.getInstalled(userId)) { 16850 // Can't block uninstall for an app that is not installed or enabled. 16851 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 16852 return false; 16853 } 16854 ps.setBlockUninstall(blockUninstall, userId); 16855 mSettings.writePackageRestrictionsLPr(userId); 16856 } 16857 return true; 16858 } 16859 16860 @Override 16861 public boolean getBlockUninstallForUser(String packageName, int userId) { 16862 synchronized (mPackages) { 16863 PackageSetting ps = mSettings.mPackages.get(packageName); 16864 if (ps == null) { 16865 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 16866 return false; 16867 } 16868 return ps.getBlockUninstall(userId); 16869 } 16870 } 16871 16872 @Override 16873 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 16874 int callingUid = Binder.getCallingUid(); 16875 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 16876 throw new SecurityException( 16877 "setRequiredForSystemUser can only be run by the system or root"); 16878 } 16879 synchronized (mPackages) { 16880 PackageSetting ps = mSettings.mPackages.get(packageName); 16881 if (ps == null) { 16882 Log.w(TAG, "Package doesn't exist: " + packageName); 16883 return false; 16884 } 16885 if (systemUserApp) { 16886 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16887 } else { 16888 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16889 } 16890 mSettings.writeLPr(); 16891 } 16892 return true; 16893 } 16894 16895 /* 16896 * This method handles package deletion in general 16897 */ 16898 private boolean deletePackageLIF(String packageName, UserHandle user, 16899 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 16900 PackageRemovedInfo outInfo, boolean writeSettings, 16901 PackageParser.Package replacingPackage) { 16902 if (packageName == null) { 16903 Slog.w(TAG, "Attempt to delete null packageName."); 16904 return false; 16905 } 16906 16907 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 16908 16909 PackageSetting ps; 16910 16911 synchronized (mPackages) { 16912 ps = mSettings.mPackages.get(packageName); 16913 if (ps == null) { 16914 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16915 return false; 16916 } 16917 16918 if (ps.parentPackageName != null && (!isSystemApp(ps) 16919 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 16920 if (DEBUG_REMOVE) { 16921 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 16922 + ((user == null) ? UserHandle.USER_ALL : user)); 16923 } 16924 final int removedUserId = (user != null) ? user.getIdentifier() 16925 : UserHandle.USER_ALL; 16926 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 16927 return false; 16928 } 16929 markPackageUninstalledForUserLPw(ps, user); 16930 scheduleWritePackageRestrictionsLocked(user); 16931 return true; 16932 } 16933 } 16934 16935 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 16936 && user.getIdentifier() != UserHandle.USER_ALL)) { 16937 // The caller is asking that the package only be deleted for a single 16938 // user. To do this, we just mark its uninstalled state and delete 16939 // its data. If this is a system app, we only allow this to happen if 16940 // they have set the special DELETE_SYSTEM_APP which requests different 16941 // semantics than normal for uninstalling system apps. 16942 markPackageUninstalledForUserLPw(ps, user); 16943 16944 if (!isSystemApp(ps)) { 16945 // Do not uninstall the APK if an app should be cached 16946 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 16947 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 16948 // Other user still have this package installed, so all 16949 // we need to do is clear this user's data and save that 16950 // it is uninstalled. 16951 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 16952 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16953 return false; 16954 } 16955 scheduleWritePackageRestrictionsLocked(user); 16956 return true; 16957 } else { 16958 // We need to set it back to 'installed' so the uninstall 16959 // broadcasts will be sent correctly. 16960 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 16961 ps.setInstalled(true, user.getIdentifier()); 16962 } 16963 } else { 16964 // This is a system app, so we assume that the 16965 // other users still have this package installed, so all 16966 // we need to do is clear this user's data and save that 16967 // it is uninstalled. 16968 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 16969 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16970 return false; 16971 } 16972 scheduleWritePackageRestrictionsLocked(user); 16973 return true; 16974 } 16975 } 16976 16977 // If we are deleting a composite package for all users, keep track 16978 // of result for each child. 16979 if (ps.childPackageNames != null && outInfo != null) { 16980 synchronized (mPackages) { 16981 final int childCount = ps.childPackageNames.size(); 16982 outInfo.removedChildPackages = new ArrayMap<>(childCount); 16983 for (int i = 0; i < childCount; i++) { 16984 String childPackageName = ps.childPackageNames.get(i); 16985 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 16986 childInfo.removedPackage = childPackageName; 16987 outInfo.removedChildPackages.put(childPackageName, childInfo); 16988 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 16989 if (childPs != null) { 16990 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 16991 } 16992 } 16993 } 16994 } 16995 16996 boolean ret = false; 16997 if (isSystemApp(ps)) { 16998 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 16999 // When an updated system application is deleted we delete the existing resources 17000 // as well and fall back to existing code in system partition 17001 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 17002 } else { 17003 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 17004 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 17005 outInfo, writeSettings, replacingPackage); 17006 } 17007 17008 // Take a note whether we deleted the package for all users 17009 if (outInfo != null) { 17010 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 17011 if (outInfo.removedChildPackages != null) { 17012 synchronized (mPackages) { 17013 final int childCount = outInfo.removedChildPackages.size(); 17014 for (int i = 0; i < childCount; i++) { 17015 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 17016 if (childInfo != null) { 17017 childInfo.removedForAllUsers = mPackages.get( 17018 childInfo.removedPackage) == null; 17019 } 17020 } 17021 } 17022 } 17023 // If we uninstalled an update to a system app there may be some 17024 // child packages that appeared as they are declared in the system 17025 // app but were not declared in the update. 17026 if (isSystemApp(ps)) { 17027 synchronized (mPackages) { 17028 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name); 17029 final int childCount = (updatedPs.childPackageNames != null) 17030 ? updatedPs.childPackageNames.size() : 0; 17031 for (int i = 0; i < childCount; i++) { 17032 String childPackageName = updatedPs.childPackageNames.get(i); 17033 if (outInfo.removedChildPackages == null 17034 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 17035 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 17036 if (childPs == null) { 17037 continue; 17038 } 17039 PackageInstalledInfo installRes = new PackageInstalledInfo(); 17040 installRes.name = childPackageName; 17041 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 17042 installRes.pkg = mPackages.get(childPackageName); 17043 installRes.uid = childPs.pkg.applicationInfo.uid; 17044 if (outInfo.appearedChildPackages == null) { 17045 outInfo.appearedChildPackages = new ArrayMap<>(); 17046 } 17047 outInfo.appearedChildPackages.put(childPackageName, installRes); 17048 } 17049 } 17050 } 17051 } 17052 } 17053 17054 return ret; 17055 } 17056 17057 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 17058 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 17059 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 17060 for (int nextUserId : userIds) { 17061 if (DEBUG_REMOVE) { 17062 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 17063 } 17064 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 17065 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 17066 false /*hidden*/, false /*suspended*/, null, null, null, 17067 false /*blockUninstall*/, 17068 ps.readUserState(nextUserId).domainVerificationStatus, 0, 17069 PackageManager.INSTALL_REASON_UNKNOWN); 17070 } 17071 } 17072 17073 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 17074 PackageRemovedInfo outInfo) { 17075 final PackageParser.Package pkg; 17076 synchronized (mPackages) { 17077 pkg = mPackages.get(ps.name); 17078 } 17079 17080 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 17081 : new int[] {userId}; 17082 for (int nextUserId : userIds) { 17083 if (DEBUG_REMOVE) { 17084 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 17085 + nextUserId); 17086 } 17087 17088 destroyAppDataLIF(pkg, userId, 17089 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 17090 destroyAppProfilesLIF(pkg, userId); 17091 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 17092 schedulePackageCleaning(ps.name, nextUserId, false); 17093 synchronized (mPackages) { 17094 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 17095 scheduleWritePackageRestrictionsLocked(nextUserId); 17096 } 17097 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 17098 } 17099 } 17100 17101 if (outInfo != null) { 17102 outInfo.removedPackage = ps.name; 17103 outInfo.removedAppId = ps.appId; 17104 outInfo.removedUsers = userIds; 17105 } 17106 17107 return true; 17108 } 17109 17110 private final class ClearStorageConnection implements ServiceConnection { 17111 IMediaContainerService mContainerService; 17112 17113 @Override 17114 public void onServiceConnected(ComponentName name, IBinder service) { 17115 synchronized (this) { 17116 mContainerService = IMediaContainerService.Stub 17117 .asInterface(Binder.allowBlocking(service)); 17118 notifyAll(); 17119 } 17120 } 17121 17122 @Override 17123 public void onServiceDisconnected(ComponentName name) { 17124 } 17125 } 17126 17127 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 17128 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 17129 17130 final boolean mounted; 17131 if (Environment.isExternalStorageEmulated()) { 17132 mounted = true; 17133 } else { 17134 final String status = Environment.getExternalStorageState(); 17135 17136 mounted = status.equals(Environment.MEDIA_MOUNTED) 17137 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 17138 } 17139 17140 if (!mounted) { 17141 return; 17142 } 17143 17144 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 17145 int[] users; 17146 if (userId == UserHandle.USER_ALL) { 17147 users = sUserManager.getUserIds(); 17148 } else { 17149 users = new int[] { userId }; 17150 } 17151 final ClearStorageConnection conn = new ClearStorageConnection(); 17152 if (mContext.bindServiceAsUser( 17153 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 17154 try { 17155 for (int curUser : users) { 17156 long timeout = SystemClock.uptimeMillis() + 5000; 17157 synchronized (conn) { 17158 long now; 17159 while (conn.mContainerService == null && 17160 (now = SystemClock.uptimeMillis()) < timeout) { 17161 try { 17162 conn.wait(timeout - now); 17163 } catch (InterruptedException e) { 17164 } 17165 } 17166 } 17167 if (conn.mContainerService == null) { 17168 return; 17169 } 17170 17171 final UserEnvironment userEnv = new UserEnvironment(curUser); 17172 clearDirectory(conn.mContainerService, 17173 userEnv.buildExternalStorageAppCacheDirs(packageName)); 17174 if (allData) { 17175 clearDirectory(conn.mContainerService, 17176 userEnv.buildExternalStorageAppDataDirs(packageName)); 17177 clearDirectory(conn.mContainerService, 17178 userEnv.buildExternalStorageAppMediaDirs(packageName)); 17179 } 17180 } 17181 } finally { 17182 mContext.unbindService(conn); 17183 } 17184 } 17185 } 17186 17187 @Override 17188 public void clearApplicationProfileData(String packageName) { 17189 enforceSystemOrRoot("Only the system can clear all profile data"); 17190 17191 final PackageParser.Package pkg; 17192 synchronized (mPackages) { 17193 pkg = mPackages.get(packageName); 17194 } 17195 17196 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 17197 synchronized (mInstallLock) { 17198 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 17199 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL, 17200 true /* removeBaseMarker */); 17201 } 17202 } 17203 } 17204 17205 @Override 17206 public void clearApplicationUserData(final String packageName, 17207 final IPackageDataObserver observer, final int userId) { 17208 mContext.enforceCallingOrSelfPermission( 17209 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 17210 17211 enforceCrossUserPermission(Binder.getCallingUid(), userId, 17212 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 17213 17214 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 17215 throw new SecurityException("Cannot clear data for a protected package: " 17216 + packageName); 17217 } 17218 // Queue up an async operation since the package deletion may take a little while. 17219 mHandler.post(new Runnable() { 17220 public void run() { 17221 mHandler.removeCallbacks(this); 17222 final boolean succeeded; 17223 try (PackageFreezer freezer = freezePackage(packageName, 17224 "clearApplicationUserData")) { 17225 synchronized (mInstallLock) { 17226 succeeded = clearApplicationUserDataLIF(packageName, userId); 17227 } 17228 clearExternalStorageDataSync(packageName, userId, true); 17229 } 17230 if (succeeded) { 17231 // invoke DeviceStorageMonitor's update method to clear any notifications 17232 DeviceStorageMonitorInternal dsm = LocalServices 17233 .getService(DeviceStorageMonitorInternal.class); 17234 if (dsm != null) { 17235 dsm.checkMemory(); 17236 } 17237 } 17238 if(observer != null) { 17239 try { 17240 observer.onRemoveCompleted(packageName, succeeded); 17241 } catch (RemoteException e) { 17242 Log.i(TAG, "Observer no longer exists."); 17243 } 17244 } //end if observer 17245 } //end run 17246 }); 17247 } 17248 17249 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 17250 if (packageName == null) { 17251 Slog.w(TAG, "Attempt to delete null packageName."); 17252 return false; 17253 } 17254 17255 // Try finding details about the requested package 17256 PackageParser.Package pkg; 17257 synchronized (mPackages) { 17258 pkg = mPackages.get(packageName); 17259 if (pkg == null) { 17260 final PackageSetting ps = mSettings.mPackages.get(packageName); 17261 if (ps != null) { 17262 pkg = ps.pkg; 17263 } 17264 } 17265 17266 if (pkg == null) { 17267 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 17268 return false; 17269 } 17270 17271 PackageSetting ps = (PackageSetting) pkg.mExtras; 17272 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 17273 } 17274 17275 clearAppDataLIF(pkg, userId, 17276 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 17277 17278 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 17279 removeKeystoreDataIfNeeded(userId, appId); 17280 17281 UserManagerInternal umInternal = getUserManagerInternal(); 17282 final int flags; 17283 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 17284 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 17285 } else if (umInternal.isUserRunning(userId)) { 17286 flags = StorageManager.FLAG_STORAGE_DE; 17287 } else { 17288 flags = 0; 17289 } 17290 prepareAppDataContentsLIF(pkg, userId, flags); 17291 17292 return true; 17293 } 17294 17295 /** 17296 * Reverts user permission state changes (permissions and flags) in 17297 * all packages for a given user. 17298 * 17299 * @param userId The device user for which to do a reset. 17300 */ 17301 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 17302 final int packageCount = mPackages.size(); 17303 for (int i = 0; i < packageCount; i++) { 17304 PackageParser.Package pkg = mPackages.valueAt(i); 17305 PackageSetting ps = (PackageSetting) pkg.mExtras; 17306 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 17307 } 17308 } 17309 17310 private void resetNetworkPolicies(int userId) { 17311 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 17312 } 17313 17314 /** 17315 * Reverts user permission state changes (permissions and flags). 17316 * 17317 * @param ps The package for which to reset. 17318 * @param userId The device user for which to do a reset. 17319 */ 17320 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 17321 final PackageSetting ps, final int userId) { 17322 if (ps.pkg == null) { 17323 return; 17324 } 17325 17326 // These are flags that can change base on user actions. 17327 final int userSettableMask = FLAG_PERMISSION_USER_SET 17328 | FLAG_PERMISSION_USER_FIXED 17329 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 17330 | FLAG_PERMISSION_REVIEW_REQUIRED; 17331 17332 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 17333 | FLAG_PERMISSION_POLICY_FIXED; 17334 17335 boolean writeInstallPermissions = false; 17336 boolean writeRuntimePermissions = false; 17337 17338 final int permissionCount = ps.pkg.requestedPermissions.size(); 17339 for (int i = 0; i < permissionCount; i++) { 17340 String permission = ps.pkg.requestedPermissions.get(i); 17341 17342 BasePermission bp = mSettings.mPermissions.get(permission); 17343 if (bp == null) { 17344 continue; 17345 } 17346 17347 // If shared user we just reset the state to which only this app contributed. 17348 if (ps.sharedUser != null) { 17349 boolean used = false; 17350 final int packageCount = ps.sharedUser.packages.size(); 17351 for (int j = 0; j < packageCount; j++) { 17352 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 17353 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 17354 && pkg.pkg.requestedPermissions.contains(permission)) { 17355 used = true; 17356 break; 17357 } 17358 } 17359 if (used) { 17360 continue; 17361 } 17362 } 17363 17364 PermissionsState permissionsState = ps.getPermissionsState(); 17365 17366 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 17367 17368 // Always clear the user settable flags. 17369 final boolean hasInstallState = permissionsState.getInstallPermissionState( 17370 bp.name) != null; 17371 // If permission review is enabled and this is a legacy app, mark the 17372 // permission as requiring a review as this is the initial state. 17373 int flags = 0; 17374 if (mPermissionReviewRequired 17375 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 17376 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 17377 } 17378 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 17379 if (hasInstallState) { 17380 writeInstallPermissions = true; 17381 } else { 17382 writeRuntimePermissions = true; 17383 } 17384 } 17385 17386 // Below is only runtime permission handling. 17387 if (!bp.isRuntime()) { 17388 continue; 17389 } 17390 17391 // Never clobber system or policy. 17392 if ((oldFlags & policyOrSystemFlags) != 0) { 17393 continue; 17394 } 17395 17396 // If this permission was granted by default, make sure it is. 17397 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 17398 if (permissionsState.grantRuntimePermission(bp, userId) 17399 != PERMISSION_OPERATION_FAILURE) { 17400 writeRuntimePermissions = true; 17401 } 17402 // If permission review is enabled the permissions for a legacy apps 17403 // are represented as constantly granted runtime ones, so don't revoke. 17404 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 17405 // Otherwise, reset the permission. 17406 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 17407 switch (revokeResult) { 17408 case PERMISSION_OPERATION_SUCCESS: 17409 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 17410 writeRuntimePermissions = true; 17411 final int appId = ps.appId; 17412 mHandler.post(new Runnable() { 17413 @Override 17414 public void run() { 17415 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 17416 } 17417 }); 17418 } break; 17419 } 17420 } 17421 } 17422 17423 // Synchronously write as we are taking permissions away. 17424 if (writeRuntimePermissions) { 17425 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 17426 } 17427 17428 // Synchronously write as we are taking permissions away. 17429 if (writeInstallPermissions) { 17430 mSettings.writeLPr(); 17431 } 17432 } 17433 17434 /** 17435 * Remove entries from the keystore daemon. Will only remove it if the 17436 * {@code appId} is valid. 17437 */ 17438 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 17439 if (appId < 0) { 17440 return; 17441 } 17442 17443 final KeyStore keyStore = KeyStore.getInstance(); 17444 if (keyStore != null) { 17445 if (userId == UserHandle.USER_ALL) { 17446 for (final int individual : sUserManager.getUserIds()) { 17447 keyStore.clearUid(UserHandle.getUid(individual, appId)); 17448 } 17449 } else { 17450 keyStore.clearUid(UserHandle.getUid(userId, appId)); 17451 } 17452 } else { 17453 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 17454 } 17455 } 17456 17457 @Override 17458 public void deleteApplicationCacheFiles(final String packageName, 17459 final IPackageDataObserver observer) { 17460 final int userId = UserHandle.getCallingUserId(); 17461 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 17462 } 17463 17464 @Override 17465 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 17466 final IPackageDataObserver observer) { 17467 mContext.enforceCallingOrSelfPermission( 17468 android.Manifest.permission.DELETE_CACHE_FILES, null); 17469 enforceCrossUserPermission(Binder.getCallingUid(), userId, 17470 /* requireFullPermission= */ true, /* checkShell= */ false, 17471 "delete application cache files"); 17472 17473 final PackageParser.Package pkg; 17474 synchronized (mPackages) { 17475 pkg = mPackages.get(packageName); 17476 } 17477 17478 // Queue up an async operation since the package deletion may take a little while. 17479 mHandler.post(new Runnable() { 17480 public void run() { 17481 synchronized (mInstallLock) { 17482 final int flags = StorageManager.FLAG_STORAGE_DE 17483 | StorageManager.FLAG_STORAGE_CE; 17484 // We're only clearing cache files, so we don't care if the 17485 // app is unfrozen and still able to run 17486 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 17487 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 17488 } 17489 clearExternalStorageDataSync(packageName, userId, false); 17490 if (observer != null) { 17491 try { 17492 observer.onRemoveCompleted(packageName, true); 17493 } catch (RemoteException e) { 17494 Log.i(TAG, "Observer no longer exists."); 17495 } 17496 } 17497 } 17498 }); 17499 } 17500 17501 @Override 17502 public void getPackageSizeInfo(final String packageName, int userHandle, 17503 final IPackageStatsObserver observer) { 17504 mContext.enforceCallingOrSelfPermission( 17505 android.Manifest.permission.GET_PACKAGE_SIZE, null); 17506 if (packageName == null) { 17507 throw new IllegalArgumentException("Attempt to get size of null packageName"); 17508 } 17509 17510 PackageStats stats = new PackageStats(packageName, userHandle); 17511 17512 /* 17513 * Queue up an async operation since the package measurement may take a 17514 * little while. 17515 */ 17516 Message msg = mHandler.obtainMessage(INIT_COPY); 17517 msg.obj = new MeasureParams(stats, observer); 17518 mHandler.sendMessage(msg); 17519 } 17520 17521 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 17522 final PackageSetting ps; 17523 synchronized (mPackages) { 17524 ps = mSettings.mPackages.get(packageName); 17525 if (ps == null) { 17526 Slog.w(TAG, "Failed to find settings for " + packageName); 17527 return false; 17528 } 17529 } 17530 17531 final String[] packageNames = { packageName }; 17532 final long[] ceDataInodes = { ps.getCeDataInode(userId) }; 17533 final String[] codePaths = { ps.codePathString }; 17534 17535 try { 17536 mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0, 17537 ps.appId, ceDataInodes, codePaths, stats); 17538 17539 // For now, ignore code size of packages on system partition 17540 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 17541 stats.codeSize = 0; 17542 } 17543 17544 // External clients expect these to be tracked separately 17545 stats.dataSize -= stats.cacheSize; 17546 17547 } catch (InstallerException e) { 17548 Slog.w(TAG, String.valueOf(e)); 17549 return false; 17550 } 17551 17552 return true; 17553 } 17554 17555 private int getUidTargetSdkVersionLockedLPr(int uid) { 17556 Object obj = mSettings.getUserIdLPr(uid); 17557 if (obj instanceof SharedUserSetting) { 17558 final SharedUserSetting sus = (SharedUserSetting) obj; 17559 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 17560 final Iterator<PackageSetting> it = sus.packages.iterator(); 17561 while (it.hasNext()) { 17562 final PackageSetting ps = it.next(); 17563 if (ps.pkg != null) { 17564 int v = ps.pkg.applicationInfo.targetSdkVersion; 17565 if (v < vers) vers = v; 17566 } 17567 } 17568 return vers; 17569 } else if (obj instanceof PackageSetting) { 17570 final PackageSetting ps = (PackageSetting) obj; 17571 if (ps.pkg != null) { 17572 return ps.pkg.applicationInfo.targetSdkVersion; 17573 } 17574 } 17575 return Build.VERSION_CODES.CUR_DEVELOPMENT; 17576 } 17577 17578 @Override 17579 public void addPreferredActivity(IntentFilter filter, int match, 17580 ComponentName[] set, ComponentName activity, int userId) { 17581 addPreferredActivityInternal(filter, match, set, activity, true, userId, 17582 "Adding preferred"); 17583 } 17584 17585 private void addPreferredActivityInternal(IntentFilter filter, int match, 17586 ComponentName[] set, ComponentName activity, boolean always, int userId, 17587 String opname) { 17588 // writer 17589 int callingUid = Binder.getCallingUid(); 17590 enforceCrossUserPermission(callingUid, userId, 17591 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 17592 if (filter.countActions() == 0) { 17593 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 17594 return; 17595 } 17596 synchronized (mPackages) { 17597 if (mContext.checkCallingOrSelfPermission( 17598 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17599 != PackageManager.PERMISSION_GRANTED) { 17600 if (getUidTargetSdkVersionLockedLPr(callingUid) 17601 < Build.VERSION_CODES.FROYO) { 17602 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 17603 + callingUid); 17604 return; 17605 } 17606 mContext.enforceCallingOrSelfPermission( 17607 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17608 } 17609 17610 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 17611 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 17612 + userId + ":"); 17613 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17614 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 17615 scheduleWritePackageRestrictionsLocked(userId); 17616 postPreferredActivityChangedBroadcast(userId); 17617 } 17618 } 17619 17620 private void postPreferredActivityChangedBroadcast(int userId) { 17621 mHandler.post(() -> { 17622 final IActivityManager am = ActivityManager.getService(); 17623 if (am == null) { 17624 return; 17625 } 17626 17627 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 17628 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17629 try { 17630 am.broadcastIntent(null, intent, null, null, 17631 0, null, null, null, android.app.AppOpsManager.OP_NONE, 17632 null, false, false, userId); 17633 } catch (RemoteException e) { 17634 } 17635 }); 17636 } 17637 17638 @Override 17639 public void replacePreferredActivity(IntentFilter filter, int match, 17640 ComponentName[] set, ComponentName activity, int userId) { 17641 if (filter.countActions() != 1) { 17642 throw new IllegalArgumentException( 17643 "replacePreferredActivity expects filter to have only 1 action."); 17644 } 17645 if (filter.countDataAuthorities() != 0 17646 || filter.countDataPaths() != 0 17647 || filter.countDataSchemes() > 1 17648 || filter.countDataTypes() != 0) { 17649 throw new IllegalArgumentException( 17650 "replacePreferredActivity expects filter to have no data authorities, " + 17651 "paths, or types; and at most one scheme."); 17652 } 17653 17654 final int callingUid = Binder.getCallingUid(); 17655 enforceCrossUserPermission(callingUid, userId, 17656 true /* requireFullPermission */, false /* checkShell */, 17657 "replace preferred activity"); 17658 synchronized (mPackages) { 17659 if (mContext.checkCallingOrSelfPermission( 17660 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17661 != PackageManager.PERMISSION_GRANTED) { 17662 if (getUidTargetSdkVersionLockedLPr(callingUid) 17663 < Build.VERSION_CODES.FROYO) { 17664 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 17665 + Binder.getCallingUid()); 17666 return; 17667 } 17668 mContext.enforceCallingOrSelfPermission( 17669 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17670 } 17671 17672 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17673 if (pir != null) { 17674 // Get all of the existing entries that exactly match this filter. 17675 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 17676 if (existing != null && existing.size() == 1) { 17677 PreferredActivity cur = existing.get(0); 17678 if (DEBUG_PREFERRED) { 17679 Slog.i(TAG, "Checking replace of preferred:"); 17680 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17681 if (!cur.mPref.mAlways) { 17682 Slog.i(TAG, " -- CUR; not mAlways!"); 17683 } else { 17684 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 17685 Slog.i(TAG, " -- CUR: mSet=" 17686 + Arrays.toString(cur.mPref.mSetComponents)); 17687 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 17688 Slog.i(TAG, " -- NEW: mMatch=" 17689 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 17690 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 17691 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 17692 } 17693 } 17694 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 17695 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 17696 && cur.mPref.sameSet(set)) { 17697 // Setting the preferred activity to what it happens to be already 17698 if (DEBUG_PREFERRED) { 17699 Slog.i(TAG, "Replacing with same preferred activity " 17700 + cur.mPref.mShortComponent + " for user " 17701 + userId + ":"); 17702 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17703 } 17704 return; 17705 } 17706 } 17707 17708 if (existing != null) { 17709 if (DEBUG_PREFERRED) { 17710 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 17711 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17712 } 17713 for (int i = 0; i < existing.size(); i++) { 17714 PreferredActivity pa = existing.get(i); 17715 if (DEBUG_PREFERRED) { 17716 Slog.i(TAG, "Removing existing preferred activity " 17717 + pa.mPref.mComponent + ":"); 17718 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 17719 } 17720 pir.removeFilter(pa); 17721 } 17722 } 17723 } 17724 addPreferredActivityInternal(filter, match, set, activity, true, userId, 17725 "Replacing preferred"); 17726 } 17727 } 17728 17729 @Override 17730 public void clearPackagePreferredActivities(String packageName) { 17731 final int uid = Binder.getCallingUid(); 17732 // writer 17733 synchronized (mPackages) { 17734 PackageParser.Package pkg = mPackages.get(packageName); 17735 if (pkg == null || pkg.applicationInfo.uid != uid) { 17736 if (mContext.checkCallingOrSelfPermission( 17737 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17738 != PackageManager.PERMISSION_GRANTED) { 17739 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 17740 < Build.VERSION_CODES.FROYO) { 17741 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 17742 + Binder.getCallingUid()); 17743 return; 17744 } 17745 mContext.enforceCallingOrSelfPermission( 17746 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17747 } 17748 } 17749 17750 int user = UserHandle.getCallingUserId(); 17751 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 17752 scheduleWritePackageRestrictionsLocked(user); 17753 } 17754 } 17755 } 17756 17757 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17758 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 17759 ArrayList<PreferredActivity> removed = null; 17760 boolean changed = false; 17761 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17762 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 17763 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17764 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 17765 continue; 17766 } 17767 Iterator<PreferredActivity> it = pir.filterIterator(); 17768 while (it.hasNext()) { 17769 PreferredActivity pa = it.next(); 17770 // Mark entry for removal only if it matches the package name 17771 // and the entry is of type "always". 17772 if (packageName == null || 17773 (pa.mPref.mComponent.getPackageName().equals(packageName) 17774 && pa.mPref.mAlways)) { 17775 if (removed == null) { 17776 removed = new ArrayList<PreferredActivity>(); 17777 } 17778 removed.add(pa); 17779 } 17780 } 17781 if (removed != null) { 17782 for (int j=0; j<removed.size(); j++) { 17783 PreferredActivity pa = removed.get(j); 17784 pir.removeFilter(pa); 17785 } 17786 changed = true; 17787 } 17788 } 17789 if (changed) { 17790 postPreferredActivityChangedBroadcast(userId); 17791 } 17792 return changed; 17793 } 17794 17795 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17796 private void clearIntentFilterVerificationsLPw(int userId) { 17797 final int packageCount = mPackages.size(); 17798 for (int i = 0; i < packageCount; i++) { 17799 PackageParser.Package pkg = mPackages.valueAt(i); 17800 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 17801 } 17802 } 17803 17804 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17805 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 17806 if (userId == UserHandle.USER_ALL) { 17807 if (mSettings.removeIntentFilterVerificationLPw(packageName, 17808 sUserManager.getUserIds())) { 17809 for (int oneUserId : sUserManager.getUserIds()) { 17810 scheduleWritePackageRestrictionsLocked(oneUserId); 17811 } 17812 } 17813 } else { 17814 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 17815 scheduleWritePackageRestrictionsLocked(userId); 17816 } 17817 } 17818 } 17819 17820 void clearDefaultBrowserIfNeeded(String packageName) { 17821 for (int oneUserId : sUserManager.getUserIds()) { 17822 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 17823 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 17824 if (packageName.equals(defaultBrowserPackageName)) { 17825 setDefaultBrowserPackageName(null, oneUserId); 17826 } 17827 } 17828 } 17829 17830 @Override 17831 public void resetApplicationPreferences(int userId) { 17832 mContext.enforceCallingOrSelfPermission( 17833 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17834 final long identity = Binder.clearCallingIdentity(); 17835 // writer 17836 try { 17837 synchronized (mPackages) { 17838 clearPackagePreferredActivitiesLPw(null, userId); 17839 mSettings.applyDefaultPreferredAppsLPw(this, userId); 17840 // TODO: We have to reset the default SMS and Phone. This requires 17841 // significant refactoring to keep all default apps in the package 17842 // manager (cleaner but more work) or have the services provide 17843 // callbacks to the package manager to request a default app reset. 17844 applyFactoryDefaultBrowserLPw(userId); 17845 clearIntentFilterVerificationsLPw(userId); 17846 primeDomainVerificationsLPw(userId); 17847 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 17848 scheduleWritePackageRestrictionsLocked(userId); 17849 } 17850 resetNetworkPolicies(userId); 17851 } finally { 17852 Binder.restoreCallingIdentity(identity); 17853 } 17854 } 17855 17856 @Override 17857 public int getPreferredActivities(List<IntentFilter> outFilters, 17858 List<ComponentName> outActivities, String packageName) { 17859 17860 int num = 0; 17861 final int userId = UserHandle.getCallingUserId(); 17862 // reader 17863 synchronized (mPackages) { 17864 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17865 if (pir != null) { 17866 final Iterator<PreferredActivity> it = pir.filterIterator(); 17867 while (it.hasNext()) { 17868 final PreferredActivity pa = it.next(); 17869 if (packageName == null 17870 || (pa.mPref.mComponent.getPackageName().equals(packageName) 17871 && pa.mPref.mAlways)) { 17872 if (outFilters != null) { 17873 outFilters.add(new IntentFilter(pa)); 17874 } 17875 if (outActivities != null) { 17876 outActivities.add(pa.mPref.mComponent); 17877 } 17878 } 17879 } 17880 } 17881 } 17882 17883 return num; 17884 } 17885 17886 @Override 17887 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 17888 int userId) { 17889 int callingUid = Binder.getCallingUid(); 17890 if (callingUid != Process.SYSTEM_UID) { 17891 throw new SecurityException( 17892 "addPersistentPreferredActivity can only be run by the system"); 17893 } 17894 if (filter.countActions() == 0) { 17895 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 17896 return; 17897 } 17898 synchronized (mPackages) { 17899 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 17900 ":"); 17901 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17902 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 17903 new PersistentPreferredActivity(filter, activity)); 17904 scheduleWritePackageRestrictionsLocked(userId); 17905 postPreferredActivityChangedBroadcast(userId); 17906 } 17907 } 17908 17909 @Override 17910 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 17911 int callingUid = Binder.getCallingUid(); 17912 if (callingUid != Process.SYSTEM_UID) { 17913 throw new SecurityException( 17914 "clearPackagePersistentPreferredActivities can only be run by the system"); 17915 } 17916 ArrayList<PersistentPreferredActivity> removed = null; 17917 boolean changed = false; 17918 synchronized (mPackages) { 17919 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 17920 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 17921 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 17922 .valueAt(i); 17923 if (userId != thisUserId) { 17924 continue; 17925 } 17926 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 17927 while (it.hasNext()) { 17928 PersistentPreferredActivity ppa = it.next(); 17929 // Mark entry for removal only if it matches the package name. 17930 if (ppa.mComponent.getPackageName().equals(packageName)) { 17931 if (removed == null) { 17932 removed = new ArrayList<PersistentPreferredActivity>(); 17933 } 17934 removed.add(ppa); 17935 } 17936 } 17937 if (removed != null) { 17938 for (int j=0; j<removed.size(); j++) { 17939 PersistentPreferredActivity ppa = removed.get(j); 17940 ppir.removeFilter(ppa); 17941 } 17942 changed = true; 17943 } 17944 } 17945 17946 if (changed) { 17947 scheduleWritePackageRestrictionsLocked(userId); 17948 postPreferredActivityChangedBroadcast(userId); 17949 } 17950 } 17951 } 17952 17953 /** 17954 * Common machinery for picking apart a restored XML blob and passing 17955 * it to a caller-supplied functor to be applied to the running system. 17956 */ 17957 private void restoreFromXml(XmlPullParser parser, int userId, 17958 String expectedStartTag, BlobXmlRestorer functor) 17959 throws IOException, XmlPullParserException { 17960 int type; 17961 while ((type = parser.next()) != XmlPullParser.START_TAG 17962 && type != XmlPullParser.END_DOCUMENT) { 17963 } 17964 if (type != XmlPullParser.START_TAG) { 17965 // oops didn't find a start tag?! 17966 if (DEBUG_BACKUP) { 17967 Slog.e(TAG, "Didn't find start tag during restore"); 17968 } 17969 return; 17970 } 17971Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 17972 // this is supposed to be TAG_PREFERRED_BACKUP 17973 if (!expectedStartTag.equals(parser.getName())) { 17974 if (DEBUG_BACKUP) { 17975 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 17976 } 17977 return; 17978 } 17979 17980 // skip interfering stuff, then we're aligned with the backing implementation 17981 while ((type = parser.next()) == XmlPullParser.TEXT) { } 17982Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 17983 functor.apply(parser, userId); 17984 } 17985 17986 private interface BlobXmlRestorer { 17987 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 17988 } 17989 17990 /** 17991 * Non-Binder method, support for the backup/restore mechanism: write the 17992 * full set of preferred activities in its canonical XML format. Returns the 17993 * XML output as a byte array, or null if there is none. 17994 */ 17995 @Override 17996 public byte[] getPreferredActivityBackup(int userId) { 17997 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17998 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 17999 } 18000 18001 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 18002 try { 18003 final XmlSerializer serializer = new FastXmlSerializer(); 18004 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 18005 serializer.startDocument(null, true); 18006 serializer.startTag(null, TAG_PREFERRED_BACKUP); 18007 18008 synchronized (mPackages) { 18009 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 18010 } 18011 18012 serializer.endTag(null, TAG_PREFERRED_BACKUP); 18013 serializer.endDocument(); 18014 serializer.flush(); 18015 } catch (Exception e) { 18016 if (DEBUG_BACKUP) { 18017 Slog.e(TAG, "Unable to write preferred activities for backup", e); 18018 } 18019 return null; 18020 } 18021 18022 return dataStream.toByteArray(); 18023 } 18024 18025 @Override 18026 public void restorePreferredActivities(byte[] backup, int userId) { 18027 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 18028 throw new SecurityException("Only the system may call restorePreferredActivities()"); 18029 } 18030 18031 try { 18032 final XmlPullParser parser = Xml.newPullParser(); 18033 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 18034 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 18035 new BlobXmlRestorer() { 18036 @Override 18037 public void apply(XmlPullParser parser, int userId) 18038 throws XmlPullParserException, IOException { 18039 synchronized (mPackages) { 18040 mSettings.readPreferredActivitiesLPw(parser, userId); 18041 } 18042 } 18043 } ); 18044 } catch (Exception e) { 18045 if (DEBUG_BACKUP) { 18046 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 18047 } 18048 } 18049 } 18050 18051 /** 18052 * Non-Binder method, support for the backup/restore mechanism: write the 18053 * default browser (etc) settings in its canonical XML format. Returns the default 18054 * browser XML representation as a byte array, or null if there is none. 18055 */ 18056 @Override 18057 public byte[] getDefaultAppsBackup(int userId) { 18058 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 18059 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 18060 } 18061 18062 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 18063 try { 18064 final XmlSerializer serializer = new FastXmlSerializer(); 18065 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 18066 serializer.startDocument(null, true); 18067 serializer.startTag(null, TAG_DEFAULT_APPS); 18068 18069 synchronized (mPackages) { 18070 mSettings.writeDefaultAppsLPr(serializer, userId); 18071 } 18072 18073 serializer.endTag(null, TAG_DEFAULT_APPS); 18074 serializer.endDocument(); 18075 serializer.flush(); 18076 } catch (Exception e) { 18077 if (DEBUG_BACKUP) { 18078 Slog.e(TAG, "Unable to write default apps for backup", e); 18079 } 18080 return null; 18081 } 18082 18083 return dataStream.toByteArray(); 18084 } 18085 18086 @Override 18087 public void restoreDefaultApps(byte[] backup, int userId) { 18088 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 18089 throw new SecurityException("Only the system may call restoreDefaultApps()"); 18090 } 18091 18092 try { 18093 final XmlPullParser parser = Xml.newPullParser(); 18094 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 18095 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 18096 new BlobXmlRestorer() { 18097 @Override 18098 public void apply(XmlPullParser parser, int userId) 18099 throws XmlPullParserException, IOException { 18100 synchronized (mPackages) { 18101 mSettings.readDefaultAppsLPw(parser, userId); 18102 } 18103 } 18104 } ); 18105 } catch (Exception e) { 18106 if (DEBUG_BACKUP) { 18107 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 18108 } 18109 } 18110 } 18111 18112 @Override 18113 public byte[] getIntentFilterVerificationBackup(int userId) { 18114 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 18115 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 18116 } 18117 18118 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 18119 try { 18120 final XmlSerializer serializer = new FastXmlSerializer(); 18121 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 18122 serializer.startDocument(null, true); 18123 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 18124 18125 synchronized (mPackages) { 18126 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 18127 } 18128 18129 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 18130 serializer.endDocument(); 18131 serializer.flush(); 18132 } catch (Exception e) { 18133 if (DEBUG_BACKUP) { 18134 Slog.e(TAG, "Unable to write default apps for backup", e); 18135 } 18136 return null; 18137 } 18138 18139 return dataStream.toByteArray(); 18140 } 18141 18142 @Override 18143 public void restoreIntentFilterVerification(byte[] backup, int userId) { 18144 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 18145 throw new SecurityException("Only the system may call restorePreferredActivities()"); 18146 } 18147 18148 try { 18149 final XmlPullParser parser = Xml.newPullParser(); 18150 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 18151 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 18152 new BlobXmlRestorer() { 18153 @Override 18154 public void apply(XmlPullParser parser, int userId) 18155 throws XmlPullParserException, IOException { 18156 synchronized (mPackages) { 18157 mSettings.readAllDomainVerificationsLPr(parser, userId); 18158 mSettings.writeLPr(); 18159 } 18160 } 18161 } ); 18162 } catch (Exception e) { 18163 if (DEBUG_BACKUP) { 18164 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 18165 } 18166 } 18167 } 18168 18169 @Override 18170 public byte[] getPermissionGrantBackup(int userId) { 18171 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 18172 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 18173 } 18174 18175 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 18176 try { 18177 final XmlSerializer serializer = new FastXmlSerializer(); 18178 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 18179 serializer.startDocument(null, true); 18180 serializer.startTag(null, TAG_PERMISSION_BACKUP); 18181 18182 synchronized (mPackages) { 18183 serializeRuntimePermissionGrantsLPr(serializer, userId); 18184 } 18185 18186 serializer.endTag(null, TAG_PERMISSION_BACKUP); 18187 serializer.endDocument(); 18188 serializer.flush(); 18189 } catch (Exception e) { 18190 if (DEBUG_BACKUP) { 18191 Slog.e(TAG, "Unable to write default apps for backup", e); 18192 } 18193 return null; 18194 } 18195 18196 return dataStream.toByteArray(); 18197 } 18198 18199 @Override 18200 public void restorePermissionGrants(byte[] backup, int userId) { 18201 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 18202 throw new SecurityException("Only the system may call restorePermissionGrants()"); 18203 } 18204 18205 try { 18206 final XmlPullParser parser = Xml.newPullParser(); 18207 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 18208 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 18209 new BlobXmlRestorer() { 18210 @Override 18211 public void apply(XmlPullParser parser, int userId) 18212 throws XmlPullParserException, IOException { 18213 synchronized (mPackages) { 18214 processRestoredPermissionGrantsLPr(parser, userId); 18215 } 18216 } 18217 } ); 18218 } catch (Exception e) { 18219 if (DEBUG_BACKUP) { 18220 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 18221 } 18222 } 18223 } 18224 18225 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 18226 throws IOException { 18227 serializer.startTag(null, TAG_ALL_GRANTS); 18228 18229 final int N = mSettings.mPackages.size(); 18230 for (int i = 0; i < N; i++) { 18231 final PackageSetting ps = mSettings.mPackages.valueAt(i); 18232 boolean pkgGrantsKnown = false; 18233 18234 PermissionsState packagePerms = ps.getPermissionsState(); 18235 18236 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 18237 final int grantFlags = state.getFlags(); 18238 // only look at grants that are not system/policy fixed 18239 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 18240 final boolean isGranted = state.isGranted(); 18241 // And only back up the user-twiddled state bits 18242 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 18243 final String packageName = mSettings.mPackages.keyAt(i); 18244 if (!pkgGrantsKnown) { 18245 serializer.startTag(null, TAG_GRANT); 18246 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 18247 pkgGrantsKnown = true; 18248 } 18249 18250 final boolean userSet = 18251 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 18252 final boolean userFixed = 18253 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 18254 final boolean revoke = 18255 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 18256 18257 serializer.startTag(null, TAG_PERMISSION); 18258 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 18259 if (isGranted) { 18260 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 18261 } 18262 if (userSet) { 18263 serializer.attribute(null, ATTR_USER_SET, "true"); 18264 } 18265 if (userFixed) { 18266 serializer.attribute(null, ATTR_USER_FIXED, "true"); 18267 } 18268 if (revoke) { 18269 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 18270 } 18271 serializer.endTag(null, TAG_PERMISSION); 18272 } 18273 } 18274 } 18275 18276 if (pkgGrantsKnown) { 18277 serializer.endTag(null, TAG_GRANT); 18278 } 18279 } 18280 18281 serializer.endTag(null, TAG_ALL_GRANTS); 18282 } 18283 18284 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 18285 throws XmlPullParserException, IOException { 18286 String pkgName = null; 18287 int outerDepth = parser.getDepth(); 18288 int type; 18289 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 18290 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 18291 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 18292 continue; 18293 } 18294 18295 final String tagName = parser.getName(); 18296 if (tagName.equals(TAG_GRANT)) { 18297 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 18298 if (DEBUG_BACKUP) { 18299 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 18300 } 18301 } else if (tagName.equals(TAG_PERMISSION)) { 18302 18303 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 18304 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 18305 18306 int newFlagSet = 0; 18307 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 18308 newFlagSet |= FLAG_PERMISSION_USER_SET; 18309 } 18310 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 18311 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 18312 } 18313 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 18314 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 18315 } 18316 if (DEBUG_BACKUP) { 18317 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 18318 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 18319 } 18320 final PackageSetting ps = mSettings.mPackages.get(pkgName); 18321 if (ps != null) { 18322 // Already installed so we apply the grant immediately 18323 if (DEBUG_BACKUP) { 18324 Slog.v(TAG, " + already installed; applying"); 18325 } 18326 PermissionsState perms = ps.getPermissionsState(); 18327 BasePermission bp = mSettings.mPermissions.get(permName); 18328 if (bp != null) { 18329 if (isGranted) { 18330 perms.grantRuntimePermission(bp, userId); 18331 } 18332 if (newFlagSet != 0) { 18333 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 18334 } 18335 } 18336 } else { 18337 // Need to wait for post-restore install to apply the grant 18338 if (DEBUG_BACKUP) { 18339 Slog.v(TAG, " - not yet installed; saving for later"); 18340 } 18341 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 18342 isGranted, newFlagSet, userId); 18343 } 18344 } else { 18345 PackageManagerService.reportSettingsProblem(Log.WARN, 18346 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 18347 XmlUtils.skipCurrentTag(parser); 18348 } 18349 } 18350 18351 scheduleWriteSettingsLocked(); 18352 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 18353 } 18354 18355 @Override 18356 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 18357 int sourceUserId, int targetUserId, int flags) { 18358 mContext.enforceCallingOrSelfPermission( 18359 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 18360 int callingUid = Binder.getCallingUid(); 18361 enforceOwnerRights(ownerPackage, callingUid); 18362 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 18363 if (intentFilter.countActions() == 0) { 18364 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 18365 return; 18366 } 18367 synchronized (mPackages) { 18368 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 18369 ownerPackage, targetUserId, flags); 18370 CrossProfileIntentResolver resolver = 18371 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 18372 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 18373 // We have all those whose filter is equal. Now checking if the rest is equal as well. 18374 if (existing != null) { 18375 int size = existing.size(); 18376 for (int i = 0; i < size; i++) { 18377 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 18378 return; 18379 } 18380 } 18381 } 18382 resolver.addFilter(newFilter); 18383 scheduleWritePackageRestrictionsLocked(sourceUserId); 18384 } 18385 } 18386 18387 @Override 18388 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 18389 mContext.enforceCallingOrSelfPermission( 18390 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 18391 int callingUid = Binder.getCallingUid(); 18392 enforceOwnerRights(ownerPackage, callingUid); 18393 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 18394 synchronized (mPackages) { 18395 CrossProfileIntentResolver resolver = 18396 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 18397 ArraySet<CrossProfileIntentFilter> set = 18398 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 18399 for (CrossProfileIntentFilter filter : set) { 18400 if (filter.getOwnerPackage().equals(ownerPackage)) { 18401 resolver.removeFilter(filter); 18402 } 18403 } 18404 scheduleWritePackageRestrictionsLocked(sourceUserId); 18405 } 18406 } 18407 18408 // Enforcing that callingUid is owning pkg on userId 18409 private void enforceOwnerRights(String pkg, int callingUid) { 18410 // The system owns everything. 18411 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 18412 return; 18413 } 18414 int callingUserId = UserHandle.getUserId(callingUid); 18415 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 18416 if (pi == null) { 18417 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 18418 + callingUserId); 18419 } 18420 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 18421 throw new SecurityException("Calling uid " + callingUid 18422 + " does not own package " + pkg); 18423 } 18424 } 18425 18426 @Override 18427 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 18428 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 18429 } 18430 18431 private Intent getHomeIntent() { 18432 Intent intent = new Intent(Intent.ACTION_MAIN); 18433 intent.addCategory(Intent.CATEGORY_HOME); 18434 intent.addCategory(Intent.CATEGORY_DEFAULT); 18435 return intent; 18436 } 18437 18438 private IntentFilter getHomeFilter() { 18439 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 18440 filter.addCategory(Intent.CATEGORY_HOME); 18441 filter.addCategory(Intent.CATEGORY_DEFAULT); 18442 return filter; 18443 } 18444 18445 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 18446 int userId) { 18447 Intent intent = getHomeIntent(); 18448 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 18449 PackageManager.GET_META_DATA, userId); 18450 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 18451 true, false, false, userId); 18452 18453 allHomeCandidates.clear(); 18454 if (list != null) { 18455 for (ResolveInfo ri : list) { 18456 allHomeCandidates.add(ri); 18457 } 18458 } 18459 return (preferred == null || preferred.activityInfo == null) 18460 ? null 18461 : new ComponentName(preferred.activityInfo.packageName, 18462 preferred.activityInfo.name); 18463 } 18464 18465 @Override 18466 public void setHomeActivity(ComponentName comp, int userId) { 18467 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 18468 getHomeActivitiesAsUser(homeActivities, userId); 18469 18470 boolean found = false; 18471 18472 final int size = homeActivities.size(); 18473 final ComponentName[] set = new ComponentName[size]; 18474 for (int i = 0; i < size; i++) { 18475 final ResolveInfo candidate = homeActivities.get(i); 18476 final ActivityInfo info = candidate.activityInfo; 18477 final ComponentName activityName = new ComponentName(info.packageName, info.name); 18478 set[i] = activityName; 18479 if (!found && activityName.equals(comp)) { 18480 found = true; 18481 } 18482 } 18483 if (!found) { 18484 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 18485 + userId); 18486 } 18487 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 18488 set, comp, userId); 18489 } 18490 18491 private @Nullable String getSetupWizardPackageName() { 18492 final Intent intent = new Intent(Intent.ACTION_MAIN); 18493 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 18494 18495 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 18496 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 18497 | MATCH_DISABLED_COMPONENTS, 18498 UserHandle.myUserId()); 18499 if (matches.size() == 1) { 18500 return matches.get(0).getComponentInfo().packageName; 18501 } else { 18502 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 18503 + ": matches=" + matches); 18504 return null; 18505 } 18506 } 18507 18508 private @Nullable String getStorageManagerPackageName() { 18509 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); 18510 18511 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 18512 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 18513 | MATCH_DISABLED_COMPONENTS, 18514 UserHandle.myUserId()); 18515 if (matches.size() == 1) { 18516 return matches.get(0).getComponentInfo().packageName; 18517 } else { 18518 Slog.e(TAG, "There should probably be exactly one storage manager; found " 18519 + matches.size() + ": matches=" + matches); 18520 return null; 18521 } 18522 } 18523 18524 @Override 18525 public void setApplicationEnabledSetting(String appPackageName, 18526 int newState, int flags, int userId, String callingPackage) { 18527 if (!sUserManager.exists(userId)) return; 18528 if (callingPackage == null) { 18529 callingPackage = Integer.toString(Binder.getCallingUid()); 18530 } 18531 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 18532 } 18533 18534 @Override 18535 public void setComponentEnabledSetting(ComponentName componentName, 18536 int newState, int flags, int userId) { 18537 if (!sUserManager.exists(userId)) return; 18538 setEnabledSetting(componentName.getPackageName(), 18539 componentName.getClassName(), newState, flags, userId, null); 18540 } 18541 18542 private void setEnabledSetting(final String packageName, String className, int newState, 18543 final int flags, int userId, String callingPackage) { 18544 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 18545 || newState == COMPONENT_ENABLED_STATE_ENABLED 18546 || newState == COMPONENT_ENABLED_STATE_DISABLED 18547 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 18548 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 18549 throw new IllegalArgumentException("Invalid new component state: " 18550 + newState); 18551 } 18552 PackageSetting pkgSetting; 18553 final int uid = Binder.getCallingUid(); 18554 final int permission; 18555 if (uid == Process.SYSTEM_UID) { 18556 permission = PackageManager.PERMISSION_GRANTED; 18557 } else { 18558 permission = mContext.checkCallingOrSelfPermission( 18559 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 18560 } 18561 enforceCrossUserPermission(uid, userId, 18562 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 18563 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 18564 boolean sendNow = false; 18565 boolean isApp = (className == null); 18566 String componentName = isApp ? packageName : className; 18567 int packageUid = -1; 18568 ArrayList<String> components; 18569 18570 // writer 18571 synchronized (mPackages) { 18572 pkgSetting = mSettings.mPackages.get(packageName); 18573 if (pkgSetting == null) { 18574 if (className == null) { 18575 throw new IllegalArgumentException("Unknown package: " + packageName); 18576 } 18577 throw new IllegalArgumentException( 18578 "Unknown component: " + packageName + "/" + className); 18579 } 18580 } 18581 18582 // Limit who can change which apps 18583 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 18584 // Don't allow apps that don't have permission to modify other apps 18585 if (!allowedByPermission) { 18586 throw new SecurityException( 18587 "Permission Denial: attempt to change component state from pid=" 18588 + Binder.getCallingPid() 18589 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 18590 } 18591 // Don't allow changing protected packages. 18592 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 18593 throw new SecurityException("Cannot disable a protected package: " + packageName); 18594 } 18595 } 18596 18597 synchronized (mPackages) { 18598 if (uid == Process.SHELL_UID 18599 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { 18600 // Shell can only change whole packages between ENABLED and DISABLED_USER states 18601 // unless it is a test package. 18602 int oldState = pkgSetting.getEnabled(userId); 18603 if (className == null 18604 && 18605 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 18606 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 18607 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 18608 && 18609 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 18610 || newState == COMPONENT_ENABLED_STATE_DEFAULT 18611 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 18612 // ok 18613 } else { 18614 throw new SecurityException( 18615 "Shell cannot change component state for " + packageName + "/" 18616 + className + " to " + newState); 18617 } 18618 } 18619 if (className == null) { 18620 // We're dealing with an application/package level state change 18621 if (pkgSetting.getEnabled(userId) == newState) { 18622 // Nothing to do 18623 return; 18624 } 18625 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 18626 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 18627 // Don't care about who enables an app. 18628 callingPackage = null; 18629 } 18630 pkgSetting.setEnabled(newState, userId, callingPackage); 18631 // pkgSetting.pkg.mSetEnabled = newState; 18632 } else { 18633 // We're dealing with a component level state change 18634 // First, verify that this is a valid class name. 18635 PackageParser.Package pkg = pkgSetting.pkg; 18636 if (pkg == null || !pkg.hasComponentClassName(className)) { 18637 if (pkg != null && 18638 pkg.applicationInfo.targetSdkVersion >= 18639 Build.VERSION_CODES.JELLY_BEAN) { 18640 throw new IllegalArgumentException("Component class " + className 18641 + " does not exist in " + packageName); 18642 } else { 18643 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 18644 + className + " does not exist in " + packageName); 18645 } 18646 } 18647 switch (newState) { 18648 case COMPONENT_ENABLED_STATE_ENABLED: 18649 if (!pkgSetting.enableComponentLPw(className, userId)) { 18650 return; 18651 } 18652 break; 18653 case COMPONENT_ENABLED_STATE_DISABLED: 18654 if (!pkgSetting.disableComponentLPw(className, userId)) { 18655 return; 18656 } 18657 break; 18658 case COMPONENT_ENABLED_STATE_DEFAULT: 18659 if (!pkgSetting.restoreComponentLPw(className, userId)) { 18660 return; 18661 } 18662 break; 18663 default: 18664 Slog.e(TAG, "Invalid new component state: " + newState); 18665 return; 18666 } 18667 } 18668 scheduleWritePackageRestrictionsLocked(userId); 18669 components = mPendingBroadcasts.get(userId, packageName); 18670 final boolean newPackage = components == null; 18671 if (newPackage) { 18672 components = new ArrayList<String>(); 18673 } 18674 if (!components.contains(componentName)) { 18675 components.add(componentName); 18676 } 18677 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 18678 sendNow = true; 18679 // Purge entry from pending broadcast list if another one exists already 18680 // since we are sending one right away. 18681 mPendingBroadcasts.remove(userId, packageName); 18682 } else { 18683 if (newPackage) { 18684 mPendingBroadcasts.put(userId, packageName, components); 18685 } 18686 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 18687 // Schedule a message 18688 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 18689 } 18690 } 18691 } 18692 18693 long callingId = Binder.clearCallingIdentity(); 18694 try { 18695 if (sendNow) { 18696 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 18697 sendPackageChangedBroadcast(packageName, 18698 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 18699 } 18700 } finally { 18701 Binder.restoreCallingIdentity(callingId); 18702 } 18703 } 18704 18705 @Override 18706 public void flushPackageRestrictionsAsUser(int userId) { 18707 if (!sUserManager.exists(userId)) { 18708 return; 18709 } 18710 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 18711 false /* checkShell */, "flushPackageRestrictions"); 18712 synchronized (mPackages) { 18713 mSettings.writePackageRestrictionsLPr(userId); 18714 mDirtyUsers.remove(userId); 18715 if (mDirtyUsers.isEmpty()) { 18716 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 18717 } 18718 } 18719 } 18720 18721 private void sendPackageChangedBroadcast(String packageName, 18722 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 18723 if (DEBUG_INSTALL) 18724 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 18725 + componentNames); 18726 Bundle extras = new Bundle(4); 18727 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 18728 String nameList[] = new String[componentNames.size()]; 18729 componentNames.toArray(nameList); 18730 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 18731 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 18732 extras.putInt(Intent.EXTRA_UID, packageUid); 18733 // If this is not reporting a change of the overall package, then only send it 18734 // to registered receivers. We don't want to launch a swath of apps for every 18735 // little component state change. 18736 final int flags = !componentNames.contains(packageName) 18737 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 18738 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 18739 new int[] {UserHandle.getUserId(packageUid)}); 18740 } 18741 18742 @Override 18743 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 18744 if (!sUserManager.exists(userId)) return; 18745 final int uid = Binder.getCallingUid(); 18746 final int permission = mContext.checkCallingOrSelfPermission( 18747 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 18748 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 18749 enforceCrossUserPermission(uid, userId, 18750 true /* requireFullPermission */, true /* checkShell */, "stop package"); 18751 // writer 18752 synchronized (mPackages) { 18753 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 18754 allowedByPermission, uid, userId)) { 18755 scheduleWritePackageRestrictionsLocked(userId); 18756 } 18757 } 18758 } 18759 18760 @Override 18761 public String getInstallerPackageName(String packageName) { 18762 // reader 18763 synchronized (mPackages) { 18764 return mSettings.getInstallerPackageNameLPr(packageName); 18765 } 18766 } 18767 18768 public boolean isOrphaned(String packageName) { 18769 // reader 18770 synchronized (mPackages) { 18771 return mSettings.isOrphaned(packageName); 18772 } 18773 } 18774 18775 @Override 18776 public int getApplicationEnabledSetting(String packageName, int userId) { 18777 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18778 int uid = Binder.getCallingUid(); 18779 enforceCrossUserPermission(uid, userId, 18780 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 18781 // reader 18782 synchronized (mPackages) { 18783 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 18784 } 18785 } 18786 18787 @Override 18788 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 18789 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18790 int uid = Binder.getCallingUid(); 18791 enforceCrossUserPermission(uid, userId, 18792 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 18793 // reader 18794 synchronized (mPackages) { 18795 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 18796 } 18797 } 18798 18799 @Override 18800 public void enterSafeMode() { 18801 enforceSystemOrRoot("Only the system can request entering safe mode"); 18802 18803 if (!mSystemReady) { 18804 mSafeMode = true; 18805 } 18806 } 18807 18808 @Override 18809 public void systemReady() { 18810 mSystemReady = true; 18811 18812 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 18813 // disabled after already being started. 18814 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 18815 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 18816 18817 // Read the compatibilty setting when the system is ready. 18818 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 18819 mContext.getContentResolver(), 18820 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 18821 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 18822 if (DEBUG_SETTINGS) { 18823 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 18824 } 18825 18826 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 18827 18828 synchronized (mPackages) { 18829 // Verify that all of the preferred activity components actually 18830 // exist. It is possible for applications to be updated and at 18831 // that point remove a previously declared activity component that 18832 // had been set as a preferred activity. We try to clean this up 18833 // the next time we encounter that preferred activity, but it is 18834 // possible for the user flow to never be able to return to that 18835 // situation so here we do a sanity check to make sure we haven't 18836 // left any junk around. 18837 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 18838 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18839 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18840 removed.clear(); 18841 for (PreferredActivity pa : pir.filterSet()) { 18842 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 18843 removed.add(pa); 18844 } 18845 } 18846 if (removed.size() > 0) { 18847 for (int r=0; r<removed.size(); r++) { 18848 PreferredActivity pa = removed.get(r); 18849 Slog.w(TAG, "Removing dangling preferred activity: " 18850 + pa.mPref.mComponent); 18851 pir.removeFilter(pa); 18852 } 18853 mSettings.writePackageRestrictionsLPr( 18854 mSettings.mPreferredActivities.keyAt(i)); 18855 } 18856 } 18857 18858 for (int userId : UserManagerService.getInstance().getUserIds()) { 18859 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 18860 grantPermissionsUserIds = ArrayUtils.appendInt( 18861 grantPermissionsUserIds, userId); 18862 } 18863 } 18864 } 18865 sUserManager.systemReady(); 18866 18867 // If we upgraded grant all default permissions before kicking off. 18868 for (int userId : grantPermissionsUserIds) { 18869 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 18870 } 18871 18872 // If we did not grant default permissions, we preload from this the 18873 // default permission exceptions lazily to ensure we don't hit the 18874 // disk on a new user creation. 18875 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 18876 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 18877 } 18878 18879 // Kick off any messages waiting for system ready 18880 if (mPostSystemReadyMessages != null) { 18881 for (Message msg : mPostSystemReadyMessages) { 18882 msg.sendToTarget(); 18883 } 18884 mPostSystemReadyMessages = null; 18885 } 18886 18887 // Watch for external volumes that come and go over time 18888 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18889 storage.registerListener(mStorageListener); 18890 18891 mInstallerService.systemReady(); 18892 mPackageDexOptimizer.systemReady(); 18893 18894 StorageManagerInternal StorageManagerInternal = LocalServices.getService( 18895 StorageManagerInternal.class); 18896 StorageManagerInternal.addExternalStoragePolicy( 18897 new StorageManagerInternal.ExternalStorageMountPolicy() { 18898 @Override 18899 public int getMountMode(int uid, String packageName) { 18900 if (Process.isIsolated(uid)) { 18901 return Zygote.MOUNT_EXTERNAL_NONE; 18902 } 18903 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 18904 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18905 } 18906 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18907 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18908 } 18909 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18910 return Zygote.MOUNT_EXTERNAL_READ; 18911 } 18912 return Zygote.MOUNT_EXTERNAL_WRITE; 18913 } 18914 18915 @Override 18916 public boolean hasExternalStorage(int uid, String packageName) { 18917 return true; 18918 } 18919 }); 18920 18921 // Now that we're mostly running, clean up stale users and apps 18922 reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 18923 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 18924 } 18925 18926 @Override 18927 public boolean isSafeMode() { 18928 return mSafeMode; 18929 } 18930 18931 @Override 18932 public boolean hasSystemUidErrors() { 18933 return mHasSystemUidErrors; 18934 } 18935 18936 static String arrayToString(int[] array) { 18937 StringBuffer buf = new StringBuffer(128); 18938 buf.append('['); 18939 if (array != null) { 18940 for (int i=0; i<array.length; i++) { 18941 if (i > 0) buf.append(", "); 18942 buf.append(array[i]); 18943 } 18944 } 18945 buf.append(']'); 18946 return buf.toString(); 18947 } 18948 18949 static class DumpState { 18950 public static final int DUMP_LIBS = 1 << 0; 18951 public static final int DUMP_FEATURES = 1 << 1; 18952 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 18953 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 18954 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 18955 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 18956 public static final int DUMP_PERMISSIONS = 1 << 6; 18957 public static final int DUMP_PACKAGES = 1 << 7; 18958 public static final int DUMP_SHARED_USERS = 1 << 8; 18959 public static final int DUMP_MESSAGES = 1 << 9; 18960 public static final int DUMP_PROVIDERS = 1 << 10; 18961 public static final int DUMP_VERIFIERS = 1 << 11; 18962 public static final int DUMP_PREFERRED = 1 << 12; 18963 public static final int DUMP_PREFERRED_XML = 1 << 13; 18964 public static final int DUMP_KEYSETS = 1 << 14; 18965 public static final int DUMP_VERSION = 1 << 15; 18966 public static final int DUMP_INSTALLS = 1 << 16; 18967 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 18968 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 18969 public static final int DUMP_FROZEN = 1 << 19; 18970 public static final int DUMP_DEXOPT = 1 << 20; 18971 public static final int DUMP_COMPILER_STATS = 1 << 21; 18972 18973 public static final int OPTION_SHOW_FILTERS = 1 << 0; 18974 18975 private int mTypes; 18976 18977 private int mOptions; 18978 18979 private boolean mTitlePrinted; 18980 18981 private SharedUserSetting mSharedUser; 18982 18983 public boolean isDumping(int type) { 18984 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 18985 return true; 18986 } 18987 18988 return (mTypes & type) != 0; 18989 } 18990 18991 public void setDump(int type) { 18992 mTypes |= type; 18993 } 18994 18995 public boolean isOptionEnabled(int option) { 18996 return (mOptions & option) != 0; 18997 } 18998 18999 public void setOptionEnabled(int option) { 19000 mOptions |= option; 19001 } 19002 19003 public boolean onTitlePrinted() { 19004 final boolean printed = mTitlePrinted; 19005 mTitlePrinted = true; 19006 return printed; 19007 } 19008 19009 public boolean getTitlePrinted() { 19010 return mTitlePrinted; 19011 } 19012 19013 public void setTitlePrinted(boolean enabled) { 19014 mTitlePrinted = enabled; 19015 } 19016 19017 public SharedUserSetting getSharedUser() { 19018 return mSharedUser; 19019 } 19020 19021 public void setSharedUser(SharedUserSetting user) { 19022 mSharedUser = user; 19023 } 19024 } 19025 19026 @Override 19027 public void onShellCommand(FileDescriptor in, FileDescriptor out, 19028 FileDescriptor err, String[] args, ShellCallback callback, 19029 ResultReceiver resultReceiver) { 19030 (new PackageManagerShellCommand(this)).exec( 19031 this, in, out, err, args, callback, resultReceiver); 19032 } 19033 19034 @Override 19035 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 19036 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 19037 != PackageManager.PERMISSION_GRANTED) { 19038 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 19039 + Binder.getCallingPid() 19040 + ", uid=" + Binder.getCallingUid() 19041 + " without permission " 19042 + android.Manifest.permission.DUMP); 19043 return; 19044 } 19045 19046 DumpState dumpState = new DumpState(); 19047 boolean fullPreferred = false; 19048 boolean checkin = false; 19049 19050 String packageName = null; 19051 ArraySet<String> permissionNames = null; 19052 19053 int opti = 0; 19054 while (opti < args.length) { 19055 String opt = args[opti]; 19056 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 19057 break; 19058 } 19059 opti++; 19060 19061 if ("-a".equals(opt)) { 19062 // Right now we only know how to print all. 19063 } else if ("-h".equals(opt)) { 19064 pw.println("Package manager dump options:"); 19065 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 19066 pw.println(" --checkin: dump for a checkin"); 19067 pw.println(" -f: print details of intent filters"); 19068 pw.println(" -h: print this help"); 19069 pw.println(" cmd may be one of:"); 19070 pw.println(" l[ibraries]: list known shared libraries"); 19071 pw.println(" f[eatures]: list device features"); 19072 pw.println(" k[eysets]: print known keysets"); 19073 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 19074 pw.println(" perm[issions]: dump permissions"); 19075 pw.println(" permission [name ...]: dump declaration and use of given permission"); 19076 pw.println(" pref[erred]: print preferred package settings"); 19077 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 19078 pw.println(" prov[iders]: dump content providers"); 19079 pw.println(" p[ackages]: dump installed packages"); 19080 pw.println(" s[hared-users]: dump shared user IDs"); 19081 pw.println(" m[essages]: print collected runtime messages"); 19082 pw.println(" v[erifiers]: print package verifier info"); 19083 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 19084 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 19085 pw.println(" version: print database version info"); 19086 pw.println(" write: write current settings now"); 19087 pw.println(" installs: details about install sessions"); 19088 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 19089 pw.println(" dexopt: dump dexopt state"); 19090 pw.println(" compiler-stats: dump compiler statistics"); 19091 pw.println(" <package.name>: info about given package"); 19092 return; 19093 } else if ("--checkin".equals(opt)) { 19094 checkin = true; 19095 } else if ("-f".equals(opt)) { 19096 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 19097 } else { 19098 pw.println("Unknown argument: " + opt + "; use -h for help"); 19099 } 19100 } 19101 19102 // Is the caller requesting to dump a particular piece of data? 19103 if (opti < args.length) { 19104 String cmd = args[opti]; 19105 opti++; 19106 // Is this a package name? 19107 if ("android".equals(cmd) || cmd.contains(".")) { 19108 packageName = cmd; 19109 // When dumping a single package, we always dump all of its 19110 // filter information since the amount of data will be reasonable. 19111 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 19112 } else if ("check-permission".equals(cmd)) { 19113 if (opti >= args.length) { 19114 pw.println("Error: check-permission missing permission argument"); 19115 return; 19116 } 19117 String perm = args[opti]; 19118 opti++; 19119 if (opti >= args.length) { 19120 pw.println("Error: check-permission missing package argument"); 19121 return; 19122 } 19123 String pkg = args[opti]; 19124 opti++; 19125 int user = UserHandle.getUserId(Binder.getCallingUid()); 19126 if (opti < args.length) { 19127 try { 19128 user = Integer.parseInt(args[opti]); 19129 } catch (NumberFormatException e) { 19130 pw.println("Error: check-permission user argument is not a number: " 19131 + args[opti]); 19132 return; 19133 } 19134 } 19135 pw.println(checkPermission(perm, pkg, user)); 19136 return; 19137 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 19138 dumpState.setDump(DumpState.DUMP_LIBS); 19139 } else if ("f".equals(cmd) || "features".equals(cmd)) { 19140 dumpState.setDump(DumpState.DUMP_FEATURES); 19141 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 19142 if (opti >= args.length) { 19143 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 19144 | DumpState.DUMP_SERVICE_RESOLVERS 19145 | DumpState.DUMP_RECEIVER_RESOLVERS 19146 | DumpState.DUMP_CONTENT_RESOLVERS); 19147 } else { 19148 while (opti < args.length) { 19149 String name = args[opti]; 19150 if ("a".equals(name) || "activity".equals(name)) { 19151 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 19152 } else if ("s".equals(name) || "service".equals(name)) { 19153 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 19154 } else if ("r".equals(name) || "receiver".equals(name)) { 19155 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 19156 } else if ("c".equals(name) || "content".equals(name)) { 19157 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 19158 } else { 19159 pw.println("Error: unknown resolver table type: " + name); 19160 return; 19161 } 19162 opti++; 19163 } 19164 } 19165 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 19166 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 19167 } else if ("permission".equals(cmd)) { 19168 if (opti >= args.length) { 19169 pw.println("Error: permission requires permission name"); 19170 return; 19171 } 19172 permissionNames = new ArraySet<>(); 19173 while (opti < args.length) { 19174 permissionNames.add(args[opti]); 19175 opti++; 19176 } 19177 dumpState.setDump(DumpState.DUMP_PERMISSIONS 19178 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 19179 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 19180 dumpState.setDump(DumpState.DUMP_PREFERRED); 19181 } else if ("preferred-xml".equals(cmd)) { 19182 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 19183 if (opti < args.length && "--full".equals(args[opti])) { 19184 fullPreferred = true; 19185 opti++; 19186 } 19187 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 19188 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 19189 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 19190 dumpState.setDump(DumpState.DUMP_PACKAGES); 19191 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 19192 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 19193 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 19194 dumpState.setDump(DumpState.DUMP_PROVIDERS); 19195 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 19196 dumpState.setDump(DumpState.DUMP_MESSAGES); 19197 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 19198 dumpState.setDump(DumpState.DUMP_VERIFIERS); 19199 } else if ("i".equals(cmd) || "ifv".equals(cmd) 19200 || "intent-filter-verifiers".equals(cmd)) { 19201 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 19202 } else if ("version".equals(cmd)) { 19203 dumpState.setDump(DumpState.DUMP_VERSION); 19204 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 19205 dumpState.setDump(DumpState.DUMP_KEYSETS); 19206 } else if ("installs".equals(cmd)) { 19207 dumpState.setDump(DumpState.DUMP_INSTALLS); 19208 } else if ("frozen".equals(cmd)) { 19209 dumpState.setDump(DumpState.DUMP_FROZEN); 19210 } else if ("dexopt".equals(cmd)) { 19211 dumpState.setDump(DumpState.DUMP_DEXOPT); 19212 } else if ("compiler-stats".equals(cmd)) { 19213 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 19214 } else if ("write".equals(cmd)) { 19215 synchronized (mPackages) { 19216 mSettings.writeLPr(); 19217 pw.println("Settings written."); 19218 return; 19219 } 19220 } 19221 } 19222 19223 if (checkin) { 19224 pw.println("vers,1"); 19225 } 19226 19227 // reader 19228 synchronized (mPackages) { 19229 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 19230 if (!checkin) { 19231 if (dumpState.onTitlePrinted()) 19232 pw.println(); 19233 pw.println("Database versions:"); 19234 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 19235 } 19236 } 19237 19238 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 19239 if (!checkin) { 19240 if (dumpState.onTitlePrinted()) 19241 pw.println(); 19242 pw.println("Verifiers:"); 19243 pw.print(" Required: "); 19244 pw.print(mRequiredVerifierPackage); 19245 pw.print(" (uid="); 19246 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 19247 UserHandle.USER_SYSTEM)); 19248 pw.println(")"); 19249 } else if (mRequiredVerifierPackage != null) { 19250 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 19251 pw.print(","); 19252 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 19253 UserHandle.USER_SYSTEM)); 19254 } 19255 } 19256 19257 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 19258 packageName == null) { 19259 if (mIntentFilterVerifierComponent != null) { 19260 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 19261 if (!checkin) { 19262 if (dumpState.onTitlePrinted()) 19263 pw.println(); 19264 pw.println("Intent Filter Verifier:"); 19265 pw.print(" Using: "); 19266 pw.print(verifierPackageName); 19267 pw.print(" (uid="); 19268 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 19269 UserHandle.USER_SYSTEM)); 19270 pw.println(")"); 19271 } else if (verifierPackageName != null) { 19272 pw.print("ifv,"); pw.print(verifierPackageName); 19273 pw.print(","); 19274 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 19275 UserHandle.USER_SYSTEM)); 19276 } 19277 } else { 19278 pw.println(); 19279 pw.println("No Intent Filter Verifier available!"); 19280 } 19281 } 19282 19283 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 19284 boolean printedHeader = false; 19285 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 19286 while (it.hasNext()) { 19287 String name = it.next(); 19288 SharedLibraryEntry ent = mSharedLibraries.get(name); 19289 if (!checkin) { 19290 if (!printedHeader) { 19291 if (dumpState.onTitlePrinted()) 19292 pw.println(); 19293 pw.println("Libraries:"); 19294 printedHeader = true; 19295 } 19296 pw.print(" "); 19297 } else { 19298 pw.print("lib,"); 19299 } 19300 pw.print(name); 19301 if (!checkin) { 19302 pw.print(" -> "); 19303 } 19304 if (ent.path != null) { 19305 if (!checkin) { 19306 pw.print("(jar) "); 19307 pw.print(ent.path); 19308 } else { 19309 pw.print(",jar,"); 19310 pw.print(ent.path); 19311 } 19312 } else { 19313 if (!checkin) { 19314 pw.print("(apk) "); 19315 pw.print(ent.apk); 19316 } else { 19317 pw.print(",apk,"); 19318 pw.print(ent.apk); 19319 } 19320 } 19321 pw.println(); 19322 } 19323 } 19324 19325 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 19326 if (dumpState.onTitlePrinted()) 19327 pw.println(); 19328 if (!checkin) { 19329 pw.println("Features:"); 19330 } 19331 19332 for (FeatureInfo feat : mAvailableFeatures.values()) { 19333 if (checkin) { 19334 pw.print("feat,"); 19335 pw.print(feat.name); 19336 pw.print(","); 19337 pw.println(feat.version); 19338 } else { 19339 pw.print(" "); 19340 pw.print(feat.name); 19341 if (feat.version > 0) { 19342 pw.print(" version="); 19343 pw.print(feat.version); 19344 } 19345 pw.println(); 19346 } 19347 } 19348 } 19349 19350 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 19351 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 19352 : "Activity Resolver Table:", " ", packageName, 19353 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 19354 dumpState.setTitlePrinted(true); 19355 } 19356 } 19357 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 19358 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 19359 : "Receiver Resolver Table:", " ", packageName, 19360 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 19361 dumpState.setTitlePrinted(true); 19362 } 19363 } 19364 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 19365 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 19366 : "Service Resolver Table:", " ", packageName, 19367 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 19368 dumpState.setTitlePrinted(true); 19369 } 19370 } 19371 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 19372 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 19373 : "Provider Resolver Table:", " ", packageName, 19374 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 19375 dumpState.setTitlePrinted(true); 19376 } 19377 } 19378 19379 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 19380 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 19381 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 19382 int user = mSettings.mPreferredActivities.keyAt(i); 19383 if (pir.dump(pw, 19384 dumpState.getTitlePrinted() 19385 ? "\nPreferred Activities User " + user + ":" 19386 : "Preferred Activities User " + user + ":", " ", 19387 packageName, true, false)) { 19388 dumpState.setTitlePrinted(true); 19389 } 19390 } 19391 } 19392 19393 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 19394 pw.flush(); 19395 FileOutputStream fout = new FileOutputStream(fd); 19396 BufferedOutputStream str = new BufferedOutputStream(fout); 19397 XmlSerializer serializer = new FastXmlSerializer(); 19398 try { 19399 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 19400 serializer.startDocument(null, true); 19401 serializer.setFeature( 19402 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 19403 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 19404 serializer.endDocument(); 19405 serializer.flush(); 19406 } catch (IllegalArgumentException e) { 19407 pw.println("Failed writing: " + e); 19408 } catch (IllegalStateException e) { 19409 pw.println("Failed writing: " + e); 19410 } catch (IOException e) { 19411 pw.println("Failed writing: " + e); 19412 } 19413 } 19414 19415 if (!checkin 19416 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 19417 && packageName == null) { 19418 pw.println(); 19419 int count = mSettings.mPackages.size(); 19420 if (count == 0) { 19421 pw.println("No applications!"); 19422 pw.println(); 19423 } else { 19424 final String prefix = " "; 19425 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 19426 if (allPackageSettings.size() == 0) { 19427 pw.println("No domain preferred apps!"); 19428 pw.println(); 19429 } else { 19430 pw.println("App verification status:"); 19431 pw.println(); 19432 count = 0; 19433 for (PackageSetting ps : allPackageSettings) { 19434 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 19435 if (ivi == null || ivi.getPackageName() == null) continue; 19436 pw.println(prefix + "Package: " + ivi.getPackageName()); 19437 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 19438 pw.println(prefix + "Status: " + ivi.getStatusString()); 19439 pw.println(); 19440 count++; 19441 } 19442 if (count == 0) { 19443 pw.println(prefix + "No app verification established."); 19444 pw.println(); 19445 } 19446 for (int userId : sUserManager.getUserIds()) { 19447 pw.println("App linkages for user " + userId + ":"); 19448 pw.println(); 19449 count = 0; 19450 for (PackageSetting ps : allPackageSettings) { 19451 final long status = ps.getDomainVerificationStatusForUser(userId); 19452 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 19453 continue; 19454 } 19455 pw.println(prefix + "Package: " + ps.name); 19456 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 19457 String statusStr = IntentFilterVerificationInfo. 19458 getStatusStringFromValue(status); 19459 pw.println(prefix + "Status: " + statusStr); 19460 pw.println(); 19461 count++; 19462 } 19463 if (count == 0) { 19464 pw.println(prefix + "No configured app linkages."); 19465 pw.println(); 19466 } 19467 } 19468 } 19469 } 19470 } 19471 19472 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 19473 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 19474 if (packageName == null && permissionNames == null) { 19475 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 19476 if (iperm == 0) { 19477 if (dumpState.onTitlePrinted()) 19478 pw.println(); 19479 pw.println("AppOp Permissions:"); 19480 } 19481 pw.print(" AppOp Permission "); 19482 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 19483 pw.println(":"); 19484 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 19485 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 19486 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 19487 } 19488 } 19489 } 19490 } 19491 19492 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 19493 boolean printedSomething = false; 19494 for (PackageParser.Provider p : mProviders.mProviders.values()) { 19495 if (packageName != null && !packageName.equals(p.info.packageName)) { 19496 continue; 19497 } 19498 if (!printedSomething) { 19499 if (dumpState.onTitlePrinted()) 19500 pw.println(); 19501 pw.println("Registered ContentProviders:"); 19502 printedSomething = true; 19503 } 19504 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 19505 pw.print(" "); pw.println(p.toString()); 19506 } 19507 printedSomething = false; 19508 for (Map.Entry<String, PackageParser.Provider> entry : 19509 mProvidersByAuthority.entrySet()) { 19510 PackageParser.Provider p = entry.getValue(); 19511 if (packageName != null && !packageName.equals(p.info.packageName)) { 19512 continue; 19513 } 19514 if (!printedSomething) { 19515 if (dumpState.onTitlePrinted()) 19516 pw.println(); 19517 pw.println("ContentProvider Authorities:"); 19518 printedSomething = true; 19519 } 19520 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 19521 pw.print(" "); pw.println(p.toString()); 19522 if (p.info != null && p.info.applicationInfo != null) { 19523 final String appInfo = p.info.applicationInfo.toString(); 19524 pw.print(" applicationInfo="); pw.println(appInfo); 19525 } 19526 } 19527 } 19528 19529 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 19530 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 19531 } 19532 19533 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 19534 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 19535 } 19536 19537 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 19538 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 19539 } 19540 19541 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 19542 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 19543 } 19544 19545 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 19546 // XXX should handle packageName != null by dumping only install data that 19547 // the given package is involved with. 19548 if (dumpState.onTitlePrinted()) pw.println(); 19549 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 19550 } 19551 19552 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 19553 // XXX should handle packageName != null by dumping only install data that 19554 // the given package is involved with. 19555 if (dumpState.onTitlePrinted()) pw.println(); 19556 19557 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 19558 ipw.println(); 19559 ipw.println("Frozen packages:"); 19560 ipw.increaseIndent(); 19561 if (mFrozenPackages.size() == 0) { 19562 ipw.println("(none)"); 19563 } else { 19564 for (int i = 0; i < mFrozenPackages.size(); i++) { 19565 ipw.println(mFrozenPackages.valueAt(i)); 19566 } 19567 } 19568 ipw.decreaseIndent(); 19569 } 19570 19571 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 19572 if (dumpState.onTitlePrinted()) pw.println(); 19573 dumpDexoptStateLPr(pw, packageName); 19574 } 19575 19576 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 19577 if (dumpState.onTitlePrinted()) pw.println(); 19578 dumpCompilerStatsLPr(pw, packageName); 19579 } 19580 19581 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 19582 if (dumpState.onTitlePrinted()) pw.println(); 19583 mSettings.dumpReadMessagesLPr(pw, dumpState); 19584 19585 pw.println(); 19586 pw.println("Package warning messages:"); 19587 BufferedReader in = null; 19588 String line = null; 19589 try { 19590 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 19591 while ((line = in.readLine()) != null) { 19592 if (line.contains("ignored: updated version")) continue; 19593 pw.println(line); 19594 } 19595 } catch (IOException ignored) { 19596 } finally { 19597 IoUtils.closeQuietly(in); 19598 } 19599 } 19600 19601 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 19602 BufferedReader in = null; 19603 String line = null; 19604 try { 19605 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 19606 while ((line = in.readLine()) != null) { 19607 if (line.contains("ignored: updated version")) continue; 19608 pw.print("msg,"); 19609 pw.println(line); 19610 } 19611 } catch (IOException ignored) { 19612 } finally { 19613 IoUtils.closeQuietly(in); 19614 } 19615 } 19616 } 19617 } 19618 19619 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 19620 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 19621 ipw.println(); 19622 ipw.println("Dexopt state:"); 19623 ipw.increaseIndent(); 19624 Collection<PackageParser.Package> packages = null; 19625 if (packageName != null) { 19626 PackageParser.Package targetPackage = mPackages.get(packageName); 19627 if (targetPackage != null) { 19628 packages = Collections.singletonList(targetPackage); 19629 } else { 19630 ipw.println("Unable to find package: " + packageName); 19631 return; 19632 } 19633 } else { 19634 packages = mPackages.values(); 19635 } 19636 19637 for (PackageParser.Package pkg : packages) { 19638 ipw.println("[" + pkg.packageName + "]"); 19639 ipw.increaseIndent(); 19640 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 19641 ipw.decreaseIndent(); 19642 } 19643 } 19644 19645 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 19646 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 19647 ipw.println(); 19648 ipw.println("Compiler stats:"); 19649 ipw.increaseIndent(); 19650 Collection<PackageParser.Package> packages = null; 19651 if (packageName != null) { 19652 PackageParser.Package targetPackage = mPackages.get(packageName); 19653 if (targetPackage != null) { 19654 packages = Collections.singletonList(targetPackage); 19655 } else { 19656 ipw.println("Unable to find package: " + packageName); 19657 return; 19658 } 19659 } else { 19660 packages = mPackages.values(); 19661 } 19662 19663 for (PackageParser.Package pkg : packages) { 19664 ipw.println("[" + pkg.packageName + "]"); 19665 ipw.increaseIndent(); 19666 19667 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 19668 if (stats == null) { 19669 ipw.println("(No recorded stats)"); 19670 } else { 19671 stats.dump(ipw); 19672 } 19673 ipw.decreaseIndent(); 19674 } 19675 } 19676 19677 private String dumpDomainString(String packageName) { 19678 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 19679 .getList(); 19680 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 19681 19682 ArraySet<String> result = new ArraySet<>(); 19683 if (iviList.size() > 0) { 19684 for (IntentFilterVerificationInfo ivi : iviList) { 19685 for (String host : ivi.getDomains()) { 19686 result.add(host); 19687 } 19688 } 19689 } 19690 if (filters != null && filters.size() > 0) { 19691 for (IntentFilter filter : filters) { 19692 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 19693 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 19694 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 19695 result.addAll(filter.getHostsList()); 19696 } 19697 } 19698 } 19699 19700 StringBuilder sb = new StringBuilder(result.size() * 16); 19701 for (String domain : result) { 19702 if (sb.length() > 0) sb.append(" "); 19703 sb.append(domain); 19704 } 19705 return sb.toString(); 19706 } 19707 19708 // ------- apps on sdcard specific code ------- 19709 static final boolean DEBUG_SD_INSTALL = false; 19710 19711 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 19712 19713 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 19714 19715 private boolean mMediaMounted = false; 19716 19717 static String getEncryptKey() { 19718 try { 19719 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 19720 SD_ENCRYPTION_KEYSTORE_NAME); 19721 if (sdEncKey == null) { 19722 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 19723 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 19724 if (sdEncKey == null) { 19725 Slog.e(TAG, "Failed to create encryption keys"); 19726 return null; 19727 } 19728 } 19729 return sdEncKey; 19730 } catch (NoSuchAlgorithmException nsae) { 19731 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 19732 return null; 19733 } catch (IOException ioe) { 19734 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 19735 return null; 19736 } 19737 } 19738 19739 /* 19740 * Update media status on PackageManager. 19741 */ 19742 @Override 19743 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 19744 int callingUid = Binder.getCallingUid(); 19745 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 19746 throw new SecurityException("Media status can only be updated by the system"); 19747 } 19748 // reader; this apparently protects mMediaMounted, but should probably 19749 // be a different lock in that case. 19750 synchronized (mPackages) { 19751 Log.i(TAG, "Updating external media status from " 19752 + (mMediaMounted ? "mounted" : "unmounted") + " to " 19753 + (mediaStatus ? "mounted" : "unmounted")); 19754 if (DEBUG_SD_INSTALL) 19755 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 19756 + ", mMediaMounted=" + mMediaMounted); 19757 if (mediaStatus == mMediaMounted) { 19758 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 19759 : 0, -1); 19760 mHandler.sendMessage(msg); 19761 return; 19762 } 19763 mMediaMounted = mediaStatus; 19764 } 19765 // Queue up an async operation since the package installation may take a 19766 // little while. 19767 mHandler.post(new Runnable() { 19768 public void run() { 19769 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 19770 } 19771 }); 19772 } 19773 19774 /** 19775 * Called by StorageManagerService when the initial ASECs to scan are available. 19776 * Should block until all the ASEC containers are finished being scanned. 19777 */ 19778 public void scanAvailableAsecs() { 19779 updateExternalMediaStatusInner(true, false, false); 19780 } 19781 19782 /* 19783 * Collect information of applications on external media, map them against 19784 * existing containers and update information based on current mount status. 19785 * Please note that we always have to report status if reportStatus has been 19786 * set to true especially when unloading packages. 19787 */ 19788 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 19789 boolean externalStorage) { 19790 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 19791 int[] uidArr = EmptyArray.INT; 19792 19793 final String[] list = PackageHelper.getSecureContainerList(); 19794 if (ArrayUtils.isEmpty(list)) { 19795 Log.i(TAG, "No secure containers found"); 19796 } else { 19797 // Process list of secure containers and categorize them 19798 // as active or stale based on their package internal state. 19799 19800 // reader 19801 synchronized (mPackages) { 19802 for (String cid : list) { 19803 // Leave stages untouched for now; installer service owns them 19804 if (PackageInstallerService.isStageName(cid)) continue; 19805 19806 if (DEBUG_SD_INSTALL) 19807 Log.i(TAG, "Processing container " + cid); 19808 String pkgName = getAsecPackageName(cid); 19809 if (pkgName == null) { 19810 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 19811 continue; 19812 } 19813 if (DEBUG_SD_INSTALL) 19814 Log.i(TAG, "Looking for pkg : " + pkgName); 19815 19816 final PackageSetting ps = mSettings.mPackages.get(pkgName); 19817 if (ps == null) { 19818 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 19819 continue; 19820 } 19821 19822 /* 19823 * Skip packages that are not external if we're unmounting 19824 * external storage. 19825 */ 19826 if (externalStorage && !isMounted && !isExternal(ps)) { 19827 continue; 19828 } 19829 19830 final AsecInstallArgs args = new AsecInstallArgs(cid, 19831 getAppDexInstructionSets(ps), ps.isForwardLocked()); 19832 // The package status is changed only if the code path 19833 // matches between settings and the container id. 19834 if (ps.codePathString != null 19835 && ps.codePathString.startsWith(args.getCodePath())) { 19836 if (DEBUG_SD_INSTALL) { 19837 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 19838 + " at code path: " + ps.codePathString); 19839 } 19840 19841 // We do have a valid package installed on sdcard 19842 processCids.put(args, ps.codePathString); 19843 final int uid = ps.appId; 19844 if (uid != -1) { 19845 uidArr = ArrayUtils.appendInt(uidArr, uid); 19846 } 19847 } else { 19848 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 19849 + ps.codePathString); 19850 } 19851 } 19852 } 19853 19854 Arrays.sort(uidArr); 19855 } 19856 19857 // Process packages with valid entries. 19858 if (isMounted) { 19859 if (DEBUG_SD_INSTALL) 19860 Log.i(TAG, "Loading packages"); 19861 loadMediaPackages(processCids, uidArr, externalStorage); 19862 startCleaningPackages(); 19863 mInstallerService.onSecureContainersAvailable(); 19864 } else { 19865 if (DEBUG_SD_INSTALL) 19866 Log.i(TAG, "Unloading packages"); 19867 unloadMediaPackages(processCids, uidArr, reportStatus); 19868 } 19869 } 19870 19871 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19872 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 19873 final int size = infos.size(); 19874 final String[] packageNames = new String[size]; 19875 final int[] packageUids = new int[size]; 19876 for (int i = 0; i < size; i++) { 19877 final ApplicationInfo info = infos.get(i); 19878 packageNames[i] = info.packageName; 19879 packageUids[i] = info.uid; 19880 } 19881 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 19882 finishedReceiver); 19883 } 19884 19885 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19886 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19887 sendResourcesChangedBroadcast(mediaStatus, replacing, 19888 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 19889 } 19890 19891 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19892 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19893 int size = pkgList.length; 19894 if (size > 0) { 19895 // Send broadcasts here 19896 Bundle extras = new Bundle(); 19897 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 19898 if (uidArr != null) { 19899 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 19900 } 19901 if (replacing) { 19902 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 19903 } 19904 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 19905 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 19906 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 19907 } 19908 } 19909 19910 /* 19911 * Look at potentially valid container ids from processCids If package 19912 * information doesn't match the one on record or package scanning fails, 19913 * the cid is added to list of removeCids. We currently don't delete stale 19914 * containers. 19915 */ 19916 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 19917 boolean externalStorage) { 19918 ArrayList<String> pkgList = new ArrayList<String>(); 19919 Set<AsecInstallArgs> keys = processCids.keySet(); 19920 19921 for (AsecInstallArgs args : keys) { 19922 String codePath = processCids.get(args); 19923 if (DEBUG_SD_INSTALL) 19924 Log.i(TAG, "Loading container : " + args.cid); 19925 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 19926 try { 19927 // Make sure there are no container errors first. 19928 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 19929 Slog.e(TAG, "Failed to mount cid : " + args.cid 19930 + " when installing from sdcard"); 19931 continue; 19932 } 19933 // Check code path here. 19934 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 19935 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 19936 + " does not match one in settings " + codePath); 19937 continue; 19938 } 19939 // Parse package 19940 int parseFlags = mDefParseFlags; 19941 if (args.isExternalAsec()) { 19942 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 19943 } 19944 if (args.isFwdLocked()) { 19945 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 19946 } 19947 19948 synchronized (mInstallLock) { 19949 PackageParser.Package pkg = null; 19950 try { 19951 // Sadly we don't know the package name yet to freeze it 19952 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 19953 SCAN_IGNORE_FROZEN, 0, null); 19954 } catch (PackageManagerException e) { 19955 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 19956 } 19957 // Scan the package 19958 if (pkg != null) { 19959 /* 19960 * TODO why is the lock being held? doPostInstall is 19961 * called in other places without the lock. This needs 19962 * to be straightened out. 19963 */ 19964 // writer 19965 synchronized (mPackages) { 19966 retCode = PackageManager.INSTALL_SUCCEEDED; 19967 pkgList.add(pkg.packageName); 19968 // Post process args 19969 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 19970 pkg.applicationInfo.uid); 19971 } 19972 } else { 19973 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 19974 } 19975 } 19976 19977 } finally { 19978 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 19979 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 19980 } 19981 } 19982 } 19983 // writer 19984 synchronized (mPackages) { 19985 // If the platform SDK has changed since the last time we booted, 19986 // we need to re-grant app permission to catch any new ones that 19987 // appear. This is really a hack, and means that apps can in some 19988 // cases get permissions that the user didn't initially explicitly 19989 // allow... it would be nice to have some better way to handle 19990 // this situation. 19991 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 19992 : mSettings.getInternalVersion(); 19993 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 19994 : StorageManager.UUID_PRIVATE_INTERNAL; 19995 19996 int updateFlags = UPDATE_PERMISSIONS_ALL; 19997 if (ver.sdkVersion != mSdkVersion) { 19998 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19999 + mSdkVersion + "; regranting permissions for external"); 20000 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 20001 } 20002 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 20003 20004 // Yay, everything is now upgraded 20005 ver.forceCurrent(); 20006 20007 // can downgrade to reader 20008 // Persist settings 20009 mSettings.writeLPr(); 20010 } 20011 // Send a broadcast to let everyone know we are done processing 20012 if (pkgList.size() > 0) { 20013 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 20014 } 20015 } 20016 20017 /* 20018 * Utility method to unload a list of specified containers 20019 */ 20020 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 20021 // Just unmount all valid containers. 20022 for (AsecInstallArgs arg : cidArgs) { 20023 synchronized (mInstallLock) { 20024 arg.doPostDeleteLI(false); 20025 } 20026 } 20027 } 20028 20029 /* 20030 * Unload packages mounted on external media. This involves deleting package 20031 * data from internal structures, sending broadcasts about disabled packages, 20032 * gc'ing to free up references, unmounting all secure containers 20033 * corresponding to packages on external media, and posting a 20034 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 20035 * that we always have to post this message if status has been requested no 20036 * matter what. 20037 */ 20038 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 20039 final boolean reportStatus) { 20040 if (DEBUG_SD_INSTALL) 20041 Log.i(TAG, "unloading media packages"); 20042 ArrayList<String> pkgList = new ArrayList<String>(); 20043 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 20044 final Set<AsecInstallArgs> keys = processCids.keySet(); 20045 for (AsecInstallArgs args : keys) { 20046 String pkgName = args.getPackageName(); 20047 if (DEBUG_SD_INSTALL) 20048 Log.i(TAG, "Trying to unload pkg : " + pkgName); 20049 // Delete package internally 20050 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 20051 synchronized (mInstallLock) { 20052 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 20053 final boolean res; 20054 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 20055 "unloadMediaPackages")) { 20056 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 20057 null); 20058 } 20059 if (res) { 20060 pkgList.add(pkgName); 20061 } else { 20062 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 20063 failedList.add(args); 20064 } 20065 } 20066 } 20067 20068 // reader 20069 synchronized (mPackages) { 20070 // We didn't update the settings after removing each package; 20071 // write them now for all packages. 20072 mSettings.writeLPr(); 20073 } 20074 20075 // We have to absolutely send UPDATED_MEDIA_STATUS only 20076 // after confirming that all the receivers processed the ordered 20077 // broadcast when packages get disabled, force a gc to clean things up. 20078 // and unload all the containers. 20079 if (pkgList.size() > 0) { 20080 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 20081 new IIntentReceiver.Stub() { 20082 public void performReceive(Intent intent, int resultCode, String data, 20083 Bundle extras, boolean ordered, boolean sticky, 20084 int sendingUser) throws RemoteException { 20085 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 20086 reportStatus ? 1 : 0, 1, keys); 20087 mHandler.sendMessage(msg); 20088 } 20089 }); 20090 } else { 20091 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 20092 keys); 20093 mHandler.sendMessage(msg); 20094 } 20095 } 20096 20097 private void loadPrivatePackages(final VolumeInfo vol) { 20098 mHandler.post(new Runnable() { 20099 @Override 20100 public void run() { 20101 loadPrivatePackagesInner(vol); 20102 } 20103 }); 20104 } 20105 20106 private void loadPrivatePackagesInner(VolumeInfo vol) { 20107 final String volumeUuid = vol.fsUuid; 20108 if (TextUtils.isEmpty(volumeUuid)) { 20109 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 20110 return; 20111 } 20112 20113 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 20114 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 20115 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 20116 20117 final VersionInfo ver; 20118 final List<PackageSetting> packages; 20119 synchronized (mPackages) { 20120 ver = mSettings.findOrCreateVersion(volumeUuid); 20121 packages = mSettings.getVolumePackagesLPr(volumeUuid); 20122 } 20123 20124 for (PackageSetting ps : packages) { 20125 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 20126 synchronized (mInstallLock) { 20127 final PackageParser.Package pkg; 20128 try { 20129 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 20130 loaded.add(pkg.applicationInfo); 20131 20132 } catch (PackageManagerException e) { 20133 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 20134 } 20135 20136 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 20137 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 20138 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 20139 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 20140 } 20141 } 20142 } 20143 20144 // Reconcile app data for all started/unlocked users 20145 final StorageManager sm = mContext.getSystemService(StorageManager.class); 20146 final UserManager um = mContext.getSystemService(UserManager.class); 20147 UserManagerInternal umInternal = getUserManagerInternal(); 20148 for (UserInfo user : um.getUsers()) { 20149 final int flags; 20150 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 20151 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 20152 } else if (umInternal.isUserRunning(user.id)) { 20153 flags = StorageManager.FLAG_STORAGE_DE; 20154 } else { 20155 continue; 20156 } 20157 20158 try { 20159 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 20160 synchronized (mInstallLock) { 20161 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */); 20162 } 20163 } catch (IllegalStateException e) { 20164 // Device was probably ejected, and we'll process that event momentarily 20165 Slog.w(TAG, "Failed to prepare storage: " + e); 20166 } 20167 } 20168 20169 synchronized (mPackages) { 20170 int updateFlags = UPDATE_PERMISSIONS_ALL; 20171 if (ver.sdkVersion != mSdkVersion) { 20172 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 20173 + mSdkVersion + "; regranting permissions for " + volumeUuid); 20174 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 20175 } 20176 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 20177 20178 // Yay, everything is now upgraded 20179 ver.forceCurrent(); 20180 20181 mSettings.writeLPr(); 20182 } 20183 20184 for (PackageFreezer freezer : freezers) { 20185 freezer.close(); 20186 } 20187 20188 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 20189 sendResourcesChangedBroadcast(true, false, loaded, null); 20190 } 20191 20192 private void unloadPrivatePackages(final VolumeInfo vol) { 20193 mHandler.post(new Runnable() { 20194 @Override 20195 public void run() { 20196 unloadPrivatePackagesInner(vol); 20197 } 20198 }); 20199 } 20200 20201 private void unloadPrivatePackagesInner(VolumeInfo vol) { 20202 final String volumeUuid = vol.fsUuid; 20203 if (TextUtils.isEmpty(volumeUuid)) { 20204 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 20205 return; 20206 } 20207 20208 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 20209 synchronized (mInstallLock) { 20210 synchronized (mPackages) { 20211 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 20212 for (PackageSetting ps : packages) { 20213 if (ps.pkg == null) continue; 20214 20215 final ApplicationInfo info = ps.pkg.applicationInfo; 20216 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 20217 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 20218 20219 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 20220 "unloadPrivatePackagesInner")) { 20221 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 20222 false, null)) { 20223 unloaded.add(info); 20224 } else { 20225 Slog.w(TAG, "Failed to unload " + ps.codePath); 20226 } 20227 } 20228 20229 // Try very hard to release any references to this package 20230 // so we don't risk the system server being killed due to 20231 // open FDs 20232 AttributeCache.instance().removePackage(ps.name); 20233 } 20234 20235 mSettings.writeLPr(); 20236 } 20237 } 20238 20239 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 20240 sendResourcesChangedBroadcast(false, false, unloaded, null); 20241 20242 // Try very hard to release any references to this path so we don't risk 20243 // the system server being killed due to open FDs 20244 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 20245 20246 for (int i = 0; i < 3; i++) { 20247 System.gc(); 20248 System.runFinalization(); 20249 } 20250 } 20251 20252 /** 20253 * Prepare storage areas for given user on all mounted devices. 20254 */ 20255 void prepareUserData(int userId, int userSerial, int flags) { 20256 synchronized (mInstallLock) { 20257 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20258 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 20259 final String volumeUuid = vol.getFsUuid(); 20260 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); 20261 } 20262 } 20263 } 20264 20265 private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, 20266 boolean allowRecover) { 20267 // Prepare storage and verify that serial numbers are consistent; if 20268 // there's a mismatch we need to destroy to avoid leaking data 20269 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20270 try { 20271 storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); 20272 20273 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) { 20274 UserManagerService.enforceSerialNumber( 20275 Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial); 20276 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 20277 UserManagerService.enforceSerialNumber( 20278 Environment.getDataSystemDeDirectory(userId), userSerial); 20279 } 20280 } 20281 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) { 20282 UserManagerService.enforceSerialNumber( 20283 Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial); 20284 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 20285 UserManagerService.enforceSerialNumber( 20286 Environment.getDataSystemCeDirectory(userId), userSerial); 20287 } 20288 } 20289 20290 synchronized (mInstallLock) { 20291 mInstaller.createUserData(volumeUuid, userId, userSerial, flags); 20292 } 20293 } catch (Exception e) { 20294 logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid 20295 + " because we failed to prepare: " + e); 20296 destroyUserDataLI(volumeUuid, userId, 20297 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 20298 20299 if (allowRecover) { 20300 // Try one last time; if we fail again we're really in trouble 20301 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false); 20302 } 20303 } 20304 } 20305 20306 /** 20307 * Destroy storage areas for given user on all mounted devices. 20308 */ 20309 void destroyUserData(int userId, int flags) { 20310 synchronized (mInstallLock) { 20311 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20312 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 20313 final String volumeUuid = vol.getFsUuid(); 20314 destroyUserDataLI(volumeUuid, userId, flags); 20315 } 20316 } 20317 } 20318 20319 private void destroyUserDataLI(String volumeUuid, int userId, int flags) { 20320 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20321 try { 20322 // Clean up app data, profile data, and media data 20323 mInstaller.destroyUserData(volumeUuid, userId, flags); 20324 20325 // Clean up system data 20326 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 20327 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 20328 FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId)); 20329 FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId)); 20330 } 20331 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 20332 FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId)); 20333 } 20334 } 20335 20336 // Data with special labels is now gone, so finish the job 20337 storage.destroyUserStorage(volumeUuid, userId, flags); 20338 20339 } catch (Exception e) { 20340 logCriticalInfo(Log.WARN, 20341 "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e); 20342 } 20343 } 20344 20345 /** 20346 * Examine all users present on given mounted volume, and destroy data 20347 * belonging to users that are no longer valid, or whose user ID has been 20348 * recycled. 20349 */ 20350 private void reconcileUsers(String volumeUuid) { 20351 final List<File> files = new ArrayList<>(); 20352 Collections.addAll(files, FileUtils 20353 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid))); 20354 Collections.addAll(files, FileUtils 20355 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid))); 20356 Collections.addAll(files, FileUtils 20357 .listFilesOrEmpty(Environment.getDataSystemDeDirectory())); 20358 Collections.addAll(files, FileUtils 20359 .listFilesOrEmpty(Environment.getDataSystemCeDirectory())); 20360 for (File file : files) { 20361 if (!file.isDirectory()) continue; 20362 20363 final int userId; 20364 final UserInfo info; 20365 try { 20366 userId = Integer.parseInt(file.getName()); 20367 info = sUserManager.getUserInfo(userId); 20368 } catch (NumberFormatException e) { 20369 Slog.w(TAG, "Invalid user directory " + file); 20370 continue; 20371 } 20372 20373 boolean destroyUser = false; 20374 if (info == null) { 20375 logCriticalInfo(Log.WARN, "Destroying user directory " + file 20376 + " because no matching user was found"); 20377 destroyUser = true; 20378 } else if (!mOnlyCore) { 20379 try { 20380 UserManagerService.enforceSerialNumber(file, info.serialNumber); 20381 } catch (IOException e) { 20382 logCriticalInfo(Log.WARN, "Destroying user directory " + file 20383 + " because we failed to enforce serial number: " + e); 20384 destroyUser = true; 20385 } 20386 } 20387 20388 if (destroyUser) { 20389 synchronized (mInstallLock) { 20390 destroyUserDataLI(volumeUuid, userId, 20391 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 20392 } 20393 } 20394 } 20395 } 20396 20397 private void assertPackageKnown(String volumeUuid, String packageName) 20398 throws PackageManagerException { 20399 synchronized (mPackages) { 20400 // Normalize package name to handle renamed packages 20401 packageName = normalizePackageNameLPr(packageName); 20402 20403 final PackageSetting ps = mSettings.mPackages.get(packageName); 20404 if (ps == null) { 20405 throw new PackageManagerException("Package " + packageName + " is unknown"); 20406 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 20407 throw new PackageManagerException( 20408 "Package " + packageName + " found on unknown volume " + volumeUuid 20409 + "; expected volume " + ps.volumeUuid); 20410 } 20411 } 20412 } 20413 20414 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 20415 throws PackageManagerException { 20416 synchronized (mPackages) { 20417 // Normalize package name to handle renamed packages 20418 packageName = normalizePackageNameLPr(packageName); 20419 20420 final PackageSetting ps = mSettings.mPackages.get(packageName); 20421 if (ps == null) { 20422 throw new PackageManagerException("Package " + packageName + " is unknown"); 20423 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 20424 throw new PackageManagerException( 20425 "Package " + packageName + " found on unknown volume " + volumeUuid 20426 + "; expected volume " + ps.volumeUuid); 20427 } else if (!ps.getInstalled(userId)) { 20428 throw new PackageManagerException( 20429 "Package " + packageName + " not installed for user " + userId); 20430 } 20431 } 20432 } 20433 20434 /** 20435 * Examine all apps present on given mounted volume, and destroy apps that 20436 * aren't expected, either due to uninstallation or reinstallation on 20437 * another volume. 20438 */ 20439 private void reconcileApps(String volumeUuid) { 20440 final File[] files = FileUtils 20441 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 20442 for (File file : files) { 20443 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 20444 && !PackageInstallerService.isStageName(file.getName()); 20445 if (!isPackage) { 20446 // Ignore entries which are not packages 20447 continue; 20448 } 20449 20450 try { 20451 final PackageLite pkg = PackageParser.parsePackageLite(file, 20452 PackageParser.PARSE_MUST_BE_APK); 20453 assertPackageKnown(volumeUuid, pkg.packageName); 20454 20455 } catch (PackageParserException | PackageManagerException e) { 20456 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 20457 synchronized (mInstallLock) { 20458 removeCodePathLI(file); 20459 } 20460 } 20461 } 20462 } 20463 20464 /** 20465 * Reconcile all app data for the given user. 20466 * <p> 20467 * Verifies that directories exist and that ownership and labeling is 20468 * correct for all installed apps on all mounted volumes. 20469 */ 20470 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) { 20471 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20472 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 20473 final String volumeUuid = vol.getFsUuid(); 20474 synchronized (mInstallLock) { 20475 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData); 20476 } 20477 } 20478 } 20479 20480 /** 20481 * Reconcile all app data on given mounted volume. 20482 * <p> 20483 * Destroys app data that isn't expected, either due to uninstallation or 20484 * reinstallation on another volume. 20485 * <p> 20486 * Verifies that directories exist and that ownership and labeling is 20487 * correct for all installed apps. 20488 */ 20489 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags, 20490 boolean migrateAppData) { 20491 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 20492 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData); 20493 20494 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 20495 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 20496 20497 // First look for stale data that doesn't belong, and check if things 20498 // have changed since we did our last restorecon 20499 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 20500 if (StorageManager.isFileEncryptedNativeOrEmulated() 20501 && !StorageManager.isUserKeyUnlocked(userId)) { 20502 throw new RuntimeException( 20503 "Yikes, someone asked us to reconcile CE storage while " + userId 20504 + " was still locked; this would have caused massive data loss!"); 20505 } 20506 20507 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 20508 for (File file : files) { 20509 final String packageName = file.getName(); 20510 try { 20511 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 20512 } catch (PackageManagerException e) { 20513 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 20514 try { 20515 mInstaller.destroyAppData(volumeUuid, packageName, userId, 20516 StorageManager.FLAG_STORAGE_CE, 0); 20517 } catch (InstallerException e2) { 20518 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 20519 } 20520 } 20521 } 20522 } 20523 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 20524 final File[] files = FileUtils.listFilesOrEmpty(deDir); 20525 for (File file : files) { 20526 final String packageName = file.getName(); 20527 try { 20528 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 20529 } catch (PackageManagerException e) { 20530 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 20531 try { 20532 mInstaller.destroyAppData(volumeUuid, packageName, userId, 20533 StorageManager.FLAG_STORAGE_DE, 0); 20534 } catch (InstallerException e2) { 20535 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 20536 } 20537 } 20538 } 20539 } 20540 20541 // Ensure that data directories are ready to roll for all packages 20542 // installed for this volume and user 20543 final List<PackageSetting> packages; 20544 synchronized (mPackages) { 20545 packages = mSettings.getVolumePackagesLPr(volumeUuid); 20546 } 20547 int preparedCount = 0; 20548 for (PackageSetting ps : packages) { 20549 final String packageName = ps.name; 20550 if (ps.pkg == null) { 20551 Slog.w(TAG, "Odd, missing scanned package " + packageName); 20552 // TODO: might be due to legacy ASEC apps; we should circle back 20553 // and reconcile again once they're scanned 20554 continue; 20555 } 20556 20557 if (ps.getInstalled(userId)) { 20558 prepareAppDataLIF(ps.pkg, userId, flags); 20559 20560 if (migrateAppData && maybeMigrateAppDataLIF(ps.pkg, userId)) { 20561 // We may have just shuffled around app data directories, so 20562 // prepare them one more time 20563 prepareAppDataLIF(ps.pkg, userId, flags); 20564 } 20565 20566 preparedCount++; 20567 } 20568 } 20569 20570 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); 20571 } 20572 20573 /** 20574 * Prepare app data for the given app just after it was installed or 20575 * upgraded. This method carefully only touches users that it's installed 20576 * for, and it forces a restorecon to handle any seinfo changes. 20577 * <p> 20578 * Verifies that directories exist and that ownership and labeling is 20579 * correct for all installed apps. If there is an ownership mismatch, it 20580 * will try recovering system apps by wiping data; third-party app data is 20581 * left intact. 20582 * <p> 20583 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 20584 */ 20585 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 20586 final PackageSetting ps; 20587 synchronized (mPackages) { 20588 ps = mSettings.mPackages.get(pkg.packageName); 20589 mSettings.writeKernelMappingLPr(ps); 20590 } 20591 20592 final UserManager um = mContext.getSystemService(UserManager.class); 20593 UserManagerInternal umInternal = getUserManagerInternal(); 20594 for (UserInfo user : um.getUsers()) { 20595 final int flags; 20596 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 20597 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 20598 } else if (umInternal.isUserRunning(user.id)) { 20599 flags = StorageManager.FLAG_STORAGE_DE; 20600 } else { 20601 continue; 20602 } 20603 20604 if (ps.getInstalled(user.id)) { 20605 // TODO: when user data is locked, mark that we're still dirty 20606 prepareAppDataLIF(pkg, user.id, flags); 20607 } 20608 } 20609 } 20610 20611 /** 20612 * Prepare app data for the given app. 20613 * <p> 20614 * Verifies that directories exist and that ownership and labeling is 20615 * correct for all installed apps. If there is an ownership mismatch, this 20616 * will try recovering system apps by wiping data; third-party app data is 20617 * left intact. 20618 */ 20619 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 20620 if (pkg == null) { 20621 Slog.wtf(TAG, "Package was null!", new Throwable()); 20622 return; 20623 } 20624 prepareAppDataLeafLIF(pkg, userId, flags); 20625 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 20626 for (int i = 0; i < childCount; i++) { 20627 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 20628 } 20629 } 20630 20631 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 20632 if (DEBUG_APP_DATA) { 20633 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 20634 + Integer.toHexString(flags)); 20635 } 20636 20637 final String volumeUuid = pkg.volumeUuid; 20638 final String packageName = pkg.packageName; 20639 final ApplicationInfo app = pkg.applicationInfo; 20640 final int appId = UserHandle.getAppId(app.uid); 20641 20642 Preconditions.checkNotNull(app.seinfo); 20643 20644 long ceDataInode = -1; 20645 try { 20646 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 20647 appId, app.seinfo, app.targetSdkVersion); 20648 } catch (InstallerException e) { 20649 if (app.isSystemApp()) { 20650 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 20651 + ", but trying to recover: " + e); 20652 destroyAppDataLeafLIF(pkg, userId, flags); 20653 try { 20654 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 20655 appId, app.seinfo, app.targetSdkVersion); 20656 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 20657 } catch (InstallerException e2) { 20658 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 20659 } 20660 } else { 20661 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 20662 } 20663 } 20664 20665 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { 20666 // TODO: mark this structure as dirty so we persist it! 20667 synchronized (mPackages) { 20668 final PackageSetting ps = mSettings.mPackages.get(packageName); 20669 if (ps != null) { 20670 ps.setCeDataInode(ceDataInode, userId); 20671 } 20672 } 20673 } 20674 20675 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20676 } 20677 20678 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 20679 if (pkg == null) { 20680 Slog.wtf(TAG, "Package was null!", new Throwable()); 20681 return; 20682 } 20683 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20684 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 20685 for (int i = 0; i < childCount; i++) { 20686 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 20687 } 20688 } 20689 20690 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 20691 final String volumeUuid = pkg.volumeUuid; 20692 final String packageName = pkg.packageName; 20693 final ApplicationInfo app = pkg.applicationInfo; 20694 20695 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 20696 // Create a native library symlink only if we have native libraries 20697 // and if the native libraries are 32 bit libraries. We do not provide 20698 // this symlink for 64 bit libraries. 20699 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 20700 final String nativeLibPath = app.nativeLibraryDir; 20701 try { 20702 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 20703 nativeLibPath, userId); 20704 } catch (InstallerException e) { 20705 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 20706 } 20707 } 20708 } 20709 } 20710 20711 /** 20712 * For system apps on non-FBE devices, this method migrates any existing 20713 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 20714 * requested by the app. 20715 */ 20716 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 20717 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 20718 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 20719 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 20720 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 20721 try { 20722 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 20723 storageTarget); 20724 } catch (InstallerException e) { 20725 logCriticalInfo(Log.WARN, 20726 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 20727 } 20728 return true; 20729 } else { 20730 return false; 20731 } 20732 } 20733 20734 public PackageFreezer freezePackage(String packageName, String killReason) { 20735 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 20736 } 20737 20738 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 20739 return new PackageFreezer(packageName, userId, killReason); 20740 } 20741 20742 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 20743 String killReason) { 20744 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 20745 } 20746 20747 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 20748 String killReason) { 20749 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 20750 return new PackageFreezer(); 20751 } else { 20752 return freezePackage(packageName, userId, killReason); 20753 } 20754 } 20755 20756 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 20757 String killReason) { 20758 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 20759 } 20760 20761 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 20762 String killReason) { 20763 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 20764 return new PackageFreezer(); 20765 } else { 20766 return freezePackage(packageName, userId, killReason); 20767 } 20768 } 20769 20770 /** 20771 * Class that freezes and kills the given package upon creation, and 20772 * unfreezes it upon closing. This is typically used when doing surgery on 20773 * app code/data to prevent the app from running while you're working. 20774 */ 20775 private class PackageFreezer implements AutoCloseable { 20776 private final String mPackageName; 20777 private final PackageFreezer[] mChildren; 20778 20779 private final boolean mWeFroze; 20780 20781 private final AtomicBoolean mClosed = new AtomicBoolean(); 20782 private final CloseGuard mCloseGuard = CloseGuard.get(); 20783 20784 /** 20785 * Create and return a stub freezer that doesn't actually do anything, 20786 * typically used when someone requested 20787 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 20788 * {@link PackageManager#DELETE_DONT_KILL_APP}. 20789 */ 20790 public PackageFreezer() { 20791 mPackageName = null; 20792 mChildren = null; 20793 mWeFroze = false; 20794 mCloseGuard.open("close"); 20795 } 20796 20797 public PackageFreezer(String packageName, int userId, String killReason) { 20798 synchronized (mPackages) { 20799 mPackageName = packageName; 20800 mWeFroze = mFrozenPackages.add(mPackageName); 20801 20802 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 20803 if (ps != null) { 20804 killApplication(ps.name, ps.appId, userId, killReason); 20805 } 20806 20807 final PackageParser.Package p = mPackages.get(packageName); 20808 if (p != null && p.childPackages != null) { 20809 final int N = p.childPackages.size(); 20810 mChildren = new PackageFreezer[N]; 20811 for (int i = 0; i < N; i++) { 20812 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 20813 userId, killReason); 20814 } 20815 } else { 20816 mChildren = null; 20817 } 20818 } 20819 mCloseGuard.open("close"); 20820 } 20821 20822 @Override 20823 protected void finalize() throws Throwable { 20824 try { 20825 mCloseGuard.warnIfOpen(); 20826 close(); 20827 } finally { 20828 super.finalize(); 20829 } 20830 } 20831 20832 @Override 20833 public void close() { 20834 mCloseGuard.close(); 20835 if (mClosed.compareAndSet(false, true)) { 20836 synchronized (mPackages) { 20837 if (mWeFroze) { 20838 mFrozenPackages.remove(mPackageName); 20839 } 20840 20841 if (mChildren != null) { 20842 for (PackageFreezer freezer : mChildren) { 20843 freezer.close(); 20844 } 20845 } 20846 } 20847 } 20848 } 20849 } 20850 20851 /** 20852 * Verify that given package is currently frozen. 20853 */ 20854 private void checkPackageFrozen(String packageName) { 20855 synchronized (mPackages) { 20856 if (!mFrozenPackages.contains(packageName)) { 20857 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 20858 } 20859 } 20860 } 20861 20862 @Override 20863 public int movePackage(final String packageName, final String volumeUuid) { 20864 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20865 20866 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 20867 final int moveId = mNextMoveId.getAndIncrement(); 20868 mHandler.post(new Runnable() { 20869 @Override 20870 public void run() { 20871 try { 20872 movePackageInternal(packageName, volumeUuid, moveId, user); 20873 } catch (PackageManagerException e) { 20874 Slog.w(TAG, "Failed to move " + packageName, e); 20875 mMoveCallbacks.notifyStatusChanged(moveId, 20876 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20877 } 20878 } 20879 }); 20880 return moveId; 20881 } 20882 20883 private void movePackageInternal(final String packageName, final String volumeUuid, 20884 final int moveId, UserHandle user) throws PackageManagerException { 20885 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20886 final PackageManager pm = mContext.getPackageManager(); 20887 20888 final boolean currentAsec; 20889 final String currentVolumeUuid; 20890 final File codeFile; 20891 final String installerPackageName; 20892 final String packageAbiOverride; 20893 final int appId; 20894 final String seinfo; 20895 final String label; 20896 final int targetSdkVersion; 20897 final PackageFreezer freezer; 20898 final int[] installedUserIds; 20899 20900 // reader 20901 synchronized (mPackages) { 20902 final PackageParser.Package pkg = mPackages.get(packageName); 20903 final PackageSetting ps = mSettings.mPackages.get(packageName); 20904 if (pkg == null || ps == null) { 20905 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 20906 } 20907 20908 if (pkg.applicationInfo.isSystemApp()) { 20909 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 20910 "Cannot move system application"); 20911 } 20912 20913 if (pkg.applicationInfo.isExternalAsec()) { 20914 currentAsec = true; 20915 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 20916 } else if (pkg.applicationInfo.isForwardLocked()) { 20917 currentAsec = true; 20918 currentVolumeUuid = "forward_locked"; 20919 } else { 20920 currentAsec = false; 20921 currentVolumeUuid = ps.volumeUuid; 20922 20923 final File probe = new File(pkg.codePath); 20924 final File probeOat = new File(probe, "oat"); 20925 if (!probe.isDirectory() || !probeOat.isDirectory()) { 20926 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20927 "Move only supported for modern cluster style installs"); 20928 } 20929 } 20930 20931 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 20932 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20933 "Package already moved to " + volumeUuid); 20934 } 20935 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 20936 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 20937 "Device admin cannot be moved"); 20938 } 20939 20940 if (mFrozenPackages.contains(packageName)) { 20941 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 20942 "Failed to move already frozen package"); 20943 } 20944 20945 codeFile = new File(pkg.codePath); 20946 installerPackageName = ps.installerPackageName; 20947 packageAbiOverride = ps.cpuAbiOverrideString; 20948 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 20949 seinfo = pkg.applicationInfo.seinfo; 20950 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 20951 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 20952 freezer = freezePackage(packageName, "movePackageInternal"); 20953 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 20954 } 20955 20956 final Bundle extras = new Bundle(); 20957 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 20958 extras.putString(Intent.EXTRA_TITLE, label); 20959 mMoveCallbacks.notifyCreated(moveId, extras); 20960 20961 int installFlags; 20962 final boolean moveCompleteApp; 20963 final File measurePath; 20964 20965 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 20966 installFlags = INSTALL_INTERNAL; 20967 moveCompleteApp = !currentAsec; 20968 measurePath = Environment.getDataAppDirectory(volumeUuid); 20969 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 20970 installFlags = INSTALL_EXTERNAL; 20971 moveCompleteApp = false; 20972 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 20973 } else { 20974 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 20975 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 20976 || !volume.isMountedWritable()) { 20977 freezer.close(); 20978 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20979 "Move location not mounted private volume"); 20980 } 20981 20982 Preconditions.checkState(!currentAsec); 20983 20984 installFlags = INSTALL_INTERNAL; 20985 moveCompleteApp = true; 20986 measurePath = Environment.getDataAppDirectory(volumeUuid); 20987 } 20988 20989 final PackageStats stats = new PackageStats(null, -1); 20990 synchronized (mInstaller) { 20991 for (int userId : installedUserIds) { 20992 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 20993 freezer.close(); 20994 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20995 "Failed to measure package size"); 20996 } 20997 } 20998 } 20999 21000 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 21001 + stats.dataSize); 21002 21003 final long startFreeBytes = measurePath.getFreeSpace(); 21004 final long sizeBytes; 21005 if (moveCompleteApp) { 21006 sizeBytes = stats.codeSize + stats.dataSize; 21007 } else { 21008 sizeBytes = stats.codeSize; 21009 } 21010 21011 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 21012 freezer.close(); 21013 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 21014 "Not enough free space to move"); 21015 } 21016 21017 mMoveCallbacks.notifyStatusChanged(moveId, 10); 21018 21019 final CountDownLatch installedLatch = new CountDownLatch(1); 21020 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 21021 @Override 21022 public void onUserActionRequired(Intent intent) throws RemoteException { 21023 throw new IllegalStateException(); 21024 } 21025 21026 @Override 21027 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 21028 Bundle extras) throws RemoteException { 21029 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 21030 + PackageManager.installStatusToString(returnCode, msg)); 21031 21032 installedLatch.countDown(); 21033 freezer.close(); 21034 21035 final int status = PackageManager.installStatusToPublicStatus(returnCode); 21036 switch (status) { 21037 case PackageInstaller.STATUS_SUCCESS: 21038 mMoveCallbacks.notifyStatusChanged(moveId, 21039 PackageManager.MOVE_SUCCEEDED); 21040 break; 21041 case PackageInstaller.STATUS_FAILURE_STORAGE: 21042 mMoveCallbacks.notifyStatusChanged(moveId, 21043 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 21044 break; 21045 default: 21046 mMoveCallbacks.notifyStatusChanged(moveId, 21047 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 21048 break; 21049 } 21050 } 21051 }; 21052 21053 final MoveInfo move; 21054 if (moveCompleteApp) { 21055 // Kick off a thread to report progress estimates 21056 new Thread() { 21057 @Override 21058 public void run() { 21059 while (true) { 21060 try { 21061 if (installedLatch.await(1, TimeUnit.SECONDS)) { 21062 break; 21063 } 21064 } catch (InterruptedException ignored) { 21065 } 21066 21067 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 21068 final int progress = 10 + (int) MathUtils.constrain( 21069 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 21070 mMoveCallbacks.notifyStatusChanged(moveId, progress); 21071 } 21072 } 21073 }.start(); 21074 21075 final String dataAppName = codeFile.getName(); 21076 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 21077 dataAppName, appId, seinfo, targetSdkVersion); 21078 } else { 21079 move = null; 21080 } 21081 21082 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 21083 21084 final Message msg = mHandler.obtainMessage(INIT_COPY); 21085 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 21086 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 21087 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 21088 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/, 21089 PackageManager.INSTALL_REASON_UNKNOWN); 21090 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 21091 msg.obj = params; 21092 21093 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 21094 System.identityHashCode(msg.obj)); 21095 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 21096 System.identityHashCode(msg.obj)); 21097 21098 mHandler.sendMessage(msg); 21099 } 21100 21101 @Override 21102 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 21103 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 21104 21105 final int realMoveId = mNextMoveId.getAndIncrement(); 21106 final Bundle extras = new Bundle(); 21107 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 21108 mMoveCallbacks.notifyCreated(realMoveId, extras); 21109 21110 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 21111 @Override 21112 public void onCreated(int moveId, Bundle extras) { 21113 // Ignored 21114 } 21115 21116 @Override 21117 public void onStatusChanged(int moveId, int status, long estMillis) { 21118 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 21119 } 21120 }; 21121 21122 final StorageManager storage = mContext.getSystemService(StorageManager.class); 21123 storage.setPrimaryStorageUuid(volumeUuid, callback); 21124 return realMoveId; 21125 } 21126 21127 @Override 21128 public int getMoveStatus(int moveId) { 21129 mContext.enforceCallingOrSelfPermission( 21130 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 21131 return mMoveCallbacks.mLastStatus.get(moveId); 21132 } 21133 21134 @Override 21135 public void registerMoveCallback(IPackageMoveObserver callback) { 21136 mContext.enforceCallingOrSelfPermission( 21137 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 21138 mMoveCallbacks.register(callback); 21139 } 21140 21141 @Override 21142 public void unregisterMoveCallback(IPackageMoveObserver callback) { 21143 mContext.enforceCallingOrSelfPermission( 21144 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 21145 mMoveCallbacks.unregister(callback); 21146 } 21147 21148 @Override 21149 public boolean setInstallLocation(int loc) { 21150 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 21151 null); 21152 if (getInstallLocation() == loc) { 21153 return true; 21154 } 21155 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 21156 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 21157 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 21158 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 21159 return true; 21160 } 21161 return false; 21162 } 21163 21164 @Override 21165 public int getInstallLocation() { 21166 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 21167 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 21168 PackageHelper.APP_INSTALL_AUTO); 21169 } 21170 21171 /** Called by UserManagerService */ 21172 void cleanUpUser(UserManagerService userManager, int userHandle) { 21173 synchronized (mPackages) { 21174 mDirtyUsers.remove(userHandle); 21175 mUserNeedsBadging.delete(userHandle); 21176 mSettings.removeUserLPw(userHandle); 21177 mPendingBroadcasts.remove(userHandle); 21178 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 21179 removeUnusedPackagesLPw(userManager, userHandle); 21180 } 21181 } 21182 21183 /** 21184 * We're removing userHandle and would like to remove any downloaded packages 21185 * that are no longer in use by any other user. 21186 * @param userHandle the user being removed 21187 */ 21188 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 21189 final boolean DEBUG_CLEAN_APKS = false; 21190 int [] users = userManager.getUserIds(); 21191 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 21192 while (psit.hasNext()) { 21193 PackageSetting ps = psit.next(); 21194 if (ps.pkg == null) { 21195 continue; 21196 } 21197 final String packageName = ps.pkg.packageName; 21198 // Skip over if system app 21199 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 21200 continue; 21201 } 21202 if (DEBUG_CLEAN_APKS) { 21203 Slog.i(TAG, "Checking package " + packageName); 21204 } 21205 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 21206 if (keep) { 21207 if (DEBUG_CLEAN_APKS) { 21208 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 21209 } 21210 } else { 21211 for (int i = 0; i < users.length; i++) { 21212 if (users[i] != userHandle && ps.getInstalled(users[i])) { 21213 keep = true; 21214 if (DEBUG_CLEAN_APKS) { 21215 Slog.i(TAG, " Keeping package " + packageName + " for user " 21216 + users[i]); 21217 } 21218 break; 21219 } 21220 } 21221 } 21222 if (!keep) { 21223 if (DEBUG_CLEAN_APKS) { 21224 Slog.i(TAG, " Removing package " + packageName); 21225 } 21226 mHandler.post(new Runnable() { 21227 public void run() { 21228 deletePackageX(packageName, userHandle, 0); 21229 } //end run 21230 }); 21231 } 21232 } 21233 } 21234 21235 /** Called by UserManagerService */ 21236 void createNewUser(int userId, String[] disallowedPackages) { 21237 synchronized (mInstallLock) { 21238 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages); 21239 } 21240 synchronized (mPackages) { 21241 scheduleWritePackageRestrictionsLocked(userId); 21242 scheduleWritePackageListLocked(userId); 21243 applyFactoryDefaultBrowserLPw(userId); 21244 primeDomainVerificationsLPw(userId); 21245 } 21246 } 21247 21248 void onNewUserCreated(final int userId) { 21249 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 21250 // If permission review for legacy apps is required, we represent 21251 // dagerous permissions for such apps as always granted runtime 21252 // permissions to keep per user flag state whether review is needed. 21253 // Hence, if a new user is added we have to propagate dangerous 21254 // permission grants for these legacy apps. 21255 if (mPermissionReviewRequired) { 21256 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 21257 | UPDATE_PERMISSIONS_REPLACE_ALL); 21258 } 21259 } 21260 21261 @Override 21262 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 21263 mContext.enforceCallingOrSelfPermission( 21264 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 21265 "Only package verification agents can read the verifier device identity"); 21266 21267 synchronized (mPackages) { 21268 return mSettings.getVerifierDeviceIdentityLPw(); 21269 } 21270 } 21271 21272 @Override 21273 public void setPermissionEnforced(String permission, boolean enforced) { 21274 // TODO: Now that we no longer change GID for storage, this should to away. 21275 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 21276 "setPermissionEnforced"); 21277 if (READ_EXTERNAL_STORAGE.equals(permission)) { 21278 synchronized (mPackages) { 21279 if (mSettings.mReadExternalStorageEnforced == null 21280 || mSettings.mReadExternalStorageEnforced != enforced) { 21281 mSettings.mReadExternalStorageEnforced = enforced; 21282 mSettings.writeLPr(); 21283 } 21284 } 21285 // kill any non-foreground processes so we restart them and 21286 // grant/revoke the GID. 21287 final IActivityManager am = ActivityManager.getService(); 21288 if (am != null) { 21289 final long token = Binder.clearCallingIdentity(); 21290 try { 21291 am.killProcessesBelowForeground("setPermissionEnforcement"); 21292 } catch (RemoteException e) { 21293 } finally { 21294 Binder.restoreCallingIdentity(token); 21295 } 21296 } 21297 } else { 21298 throw new IllegalArgumentException("No selective enforcement for " + permission); 21299 } 21300 } 21301 21302 @Override 21303 @Deprecated 21304 public boolean isPermissionEnforced(String permission) { 21305 return true; 21306 } 21307 21308 @Override 21309 public boolean isStorageLow() { 21310 final long token = Binder.clearCallingIdentity(); 21311 try { 21312 final DeviceStorageMonitorInternal 21313 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 21314 if (dsm != null) { 21315 return dsm.isMemoryLow(); 21316 } else { 21317 return false; 21318 } 21319 } finally { 21320 Binder.restoreCallingIdentity(token); 21321 } 21322 } 21323 21324 @Override 21325 public IPackageInstaller getPackageInstaller() { 21326 return mInstallerService; 21327 } 21328 21329 private boolean userNeedsBadging(int userId) { 21330 int index = mUserNeedsBadging.indexOfKey(userId); 21331 if (index < 0) { 21332 final UserInfo userInfo; 21333 final long token = Binder.clearCallingIdentity(); 21334 try { 21335 userInfo = sUserManager.getUserInfo(userId); 21336 } finally { 21337 Binder.restoreCallingIdentity(token); 21338 } 21339 final boolean b; 21340 if (userInfo != null && userInfo.isManagedProfile()) { 21341 b = true; 21342 } else { 21343 b = false; 21344 } 21345 mUserNeedsBadging.put(userId, b); 21346 return b; 21347 } 21348 return mUserNeedsBadging.valueAt(index); 21349 } 21350 21351 @Override 21352 public KeySet getKeySetByAlias(String packageName, String alias) { 21353 if (packageName == null || alias == null) { 21354 return null; 21355 } 21356 synchronized(mPackages) { 21357 final PackageParser.Package pkg = mPackages.get(packageName); 21358 if (pkg == null) { 21359 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 21360 throw new IllegalArgumentException("Unknown package: " + packageName); 21361 } 21362 KeySetManagerService ksms = mSettings.mKeySetManagerService; 21363 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 21364 } 21365 } 21366 21367 @Override 21368 public KeySet getSigningKeySet(String packageName) { 21369 if (packageName == null) { 21370 return null; 21371 } 21372 synchronized(mPackages) { 21373 final PackageParser.Package pkg = mPackages.get(packageName); 21374 if (pkg == null) { 21375 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 21376 throw new IllegalArgumentException("Unknown package: " + packageName); 21377 } 21378 if (pkg.applicationInfo.uid != Binder.getCallingUid() 21379 && Process.SYSTEM_UID != Binder.getCallingUid()) { 21380 throw new SecurityException("May not access signing KeySet of other apps."); 21381 } 21382 KeySetManagerService ksms = mSettings.mKeySetManagerService; 21383 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 21384 } 21385 } 21386 21387 @Override 21388 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 21389 if (packageName == null || ks == null) { 21390 return false; 21391 } 21392 synchronized(mPackages) { 21393 final PackageParser.Package pkg = mPackages.get(packageName); 21394 if (pkg == null) { 21395 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 21396 throw new IllegalArgumentException("Unknown package: " + packageName); 21397 } 21398 IBinder ksh = ks.getToken(); 21399 if (ksh instanceof KeySetHandle) { 21400 KeySetManagerService ksms = mSettings.mKeySetManagerService; 21401 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 21402 } 21403 return false; 21404 } 21405 } 21406 21407 @Override 21408 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 21409 if (packageName == null || ks == null) { 21410 return false; 21411 } 21412 synchronized(mPackages) { 21413 final PackageParser.Package pkg = mPackages.get(packageName); 21414 if (pkg == null) { 21415 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 21416 throw new IllegalArgumentException("Unknown package: " + packageName); 21417 } 21418 IBinder ksh = ks.getToken(); 21419 if (ksh instanceof KeySetHandle) { 21420 KeySetManagerService ksms = mSettings.mKeySetManagerService; 21421 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 21422 } 21423 return false; 21424 } 21425 } 21426 21427 private void deletePackageIfUnusedLPr(final String packageName) { 21428 PackageSetting ps = mSettings.mPackages.get(packageName); 21429 if (ps == null) { 21430 return; 21431 } 21432 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 21433 // TODO Implement atomic delete if package is unused 21434 // It is currently possible that the package will be deleted even if it is installed 21435 // after this method returns. 21436 mHandler.post(new Runnable() { 21437 public void run() { 21438 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 21439 } 21440 }); 21441 } 21442 } 21443 21444 /** 21445 * Check and throw if the given before/after packages would be considered a 21446 * downgrade. 21447 */ 21448 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 21449 throws PackageManagerException { 21450 if (after.versionCode < before.mVersionCode) { 21451 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 21452 "Update version code " + after.versionCode + " is older than current " 21453 + before.mVersionCode); 21454 } else if (after.versionCode == before.mVersionCode) { 21455 if (after.baseRevisionCode < before.baseRevisionCode) { 21456 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 21457 "Update base revision code " + after.baseRevisionCode 21458 + " is older than current " + before.baseRevisionCode); 21459 } 21460 21461 if (!ArrayUtils.isEmpty(after.splitNames)) { 21462 for (int i = 0; i < after.splitNames.length; i++) { 21463 final String splitName = after.splitNames[i]; 21464 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 21465 if (j != -1) { 21466 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 21467 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 21468 "Update split " + splitName + " revision code " 21469 + after.splitRevisionCodes[i] + " is older than current " 21470 + before.splitRevisionCodes[j]); 21471 } 21472 } 21473 } 21474 } 21475 } 21476 } 21477 21478 private static class MoveCallbacks extends Handler { 21479 private static final int MSG_CREATED = 1; 21480 private static final int MSG_STATUS_CHANGED = 2; 21481 21482 private final RemoteCallbackList<IPackageMoveObserver> 21483 mCallbacks = new RemoteCallbackList<>(); 21484 21485 private final SparseIntArray mLastStatus = new SparseIntArray(); 21486 21487 public MoveCallbacks(Looper looper) { 21488 super(looper); 21489 } 21490 21491 public void register(IPackageMoveObserver callback) { 21492 mCallbacks.register(callback); 21493 } 21494 21495 public void unregister(IPackageMoveObserver callback) { 21496 mCallbacks.unregister(callback); 21497 } 21498 21499 @Override 21500 public void handleMessage(Message msg) { 21501 final SomeArgs args = (SomeArgs) msg.obj; 21502 final int n = mCallbacks.beginBroadcast(); 21503 for (int i = 0; i < n; i++) { 21504 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 21505 try { 21506 invokeCallback(callback, msg.what, args); 21507 } catch (RemoteException ignored) { 21508 } 21509 } 21510 mCallbacks.finishBroadcast(); 21511 args.recycle(); 21512 } 21513 21514 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 21515 throws RemoteException { 21516 switch (what) { 21517 case MSG_CREATED: { 21518 callback.onCreated(args.argi1, (Bundle) args.arg2); 21519 break; 21520 } 21521 case MSG_STATUS_CHANGED: { 21522 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 21523 break; 21524 } 21525 } 21526 } 21527 21528 private void notifyCreated(int moveId, Bundle extras) { 21529 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 21530 21531 final SomeArgs args = SomeArgs.obtain(); 21532 args.argi1 = moveId; 21533 args.arg2 = extras; 21534 obtainMessage(MSG_CREATED, args).sendToTarget(); 21535 } 21536 21537 private void notifyStatusChanged(int moveId, int status) { 21538 notifyStatusChanged(moveId, status, -1); 21539 } 21540 21541 private void notifyStatusChanged(int moveId, int status, long estMillis) { 21542 Slog.v(TAG, "Move " + moveId + " status " + status); 21543 21544 final SomeArgs args = SomeArgs.obtain(); 21545 args.argi1 = moveId; 21546 args.argi2 = status; 21547 args.arg3 = estMillis; 21548 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 21549 21550 synchronized (mLastStatus) { 21551 mLastStatus.put(moveId, status); 21552 } 21553 } 21554 } 21555 21556 private final static class OnPermissionChangeListeners extends Handler { 21557 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 21558 21559 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 21560 new RemoteCallbackList<>(); 21561 21562 public OnPermissionChangeListeners(Looper looper) { 21563 super(looper); 21564 } 21565 21566 @Override 21567 public void handleMessage(Message msg) { 21568 switch (msg.what) { 21569 case MSG_ON_PERMISSIONS_CHANGED: { 21570 final int uid = msg.arg1; 21571 handleOnPermissionsChanged(uid); 21572 } break; 21573 } 21574 } 21575 21576 public void addListenerLocked(IOnPermissionsChangeListener listener) { 21577 mPermissionListeners.register(listener); 21578 21579 } 21580 21581 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 21582 mPermissionListeners.unregister(listener); 21583 } 21584 21585 public void onPermissionsChanged(int uid) { 21586 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 21587 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 21588 } 21589 } 21590 21591 private void handleOnPermissionsChanged(int uid) { 21592 final int count = mPermissionListeners.beginBroadcast(); 21593 try { 21594 for (int i = 0; i < count; i++) { 21595 IOnPermissionsChangeListener callback = mPermissionListeners 21596 .getBroadcastItem(i); 21597 try { 21598 callback.onPermissionsChanged(uid); 21599 } catch (RemoteException e) { 21600 Log.e(TAG, "Permission listener is dead", e); 21601 } 21602 } 21603 } finally { 21604 mPermissionListeners.finishBroadcast(); 21605 } 21606 } 21607 } 21608 21609 private class PackageManagerInternalImpl extends PackageManagerInternal { 21610 @Override 21611 public void setLocationPackagesProvider(PackagesProvider provider) { 21612 synchronized (mPackages) { 21613 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 21614 } 21615 } 21616 21617 @Override 21618 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 21619 synchronized (mPackages) { 21620 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 21621 } 21622 } 21623 21624 @Override 21625 public void setSmsAppPackagesProvider(PackagesProvider provider) { 21626 synchronized (mPackages) { 21627 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 21628 } 21629 } 21630 21631 @Override 21632 public void setDialerAppPackagesProvider(PackagesProvider provider) { 21633 synchronized (mPackages) { 21634 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 21635 } 21636 } 21637 21638 @Override 21639 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 21640 synchronized (mPackages) { 21641 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 21642 } 21643 } 21644 21645 @Override 21646 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 21647 synchronized (mPackages) { 21648 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 21649 } 21650 } 21651 21652 @Override 21653 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 21654 synchronized (mPackages) { 21655 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 21656 packageName, userId); 21657 } 21658 } 21659 21660 @Override 21661 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 21662 synchronized (mPackages) { 21663 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 21664 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 21665 packageName, userId); 21666 } 21667 } 21668 21669 @Override 21670 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 21671 synchronized (mPackages) { 21672 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 21673 packageName, userId); 21674 } 21675 } 21676 21677 @Override 21678 public void setKeepUninstalledPackages(final List<String> packageList) { 21679 Preconditions.checkNotNull(packageList); 21680 List<String> removedFromList = null; 21681 synchronized (mPackages) { 21682 if (mKeepUninstalledPackages != null) { 21683 final int packagesCount = mKeepUninstalledPackages.size(); 21684 for (int i = 0; i < packagesCount; i++) { 21685 String oldPackage = mKeepUninstalledPackages.get(i); 21686 if (packageList != null && packageList.contains(oldPackage)) { 21687 continue; 21688 } 21689 if (removedFromList == null) { 21690 removedFromList = new ArrayList<>(); 21691 } 21692 removedFromList.add(oldPackage); 21693 } 21694 } 21695 mKeepUninstalledPackages = new ArrayList<>(packageList); 21696 if (removedFromList != null) { 21697 final int removedCount = removedFromList.size(); 21698 for (int i = 0; i < removedCount; i++) { 21699 deletePackageIfUnusedLPr(removedFromList.get(i)); 21700 } 21701 } 21702 } 21703 } 21704 21705 @Override 21706 public boolean isPermissionsReviewRequired(String packageName, int userId) { 21707 synchronized (mPackages) { 21708 // If we do not support permission review, done. 21709 if (!mPermissionReviewRequired) { 21710 return false; 21711 } 21712 21713 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 21714 if (packageSetting == null) { 21715 return false; 21716 } 21717 21718 // Permission review applies only to apps not supporting the new permission model. 21719 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 21720 return false; 21721 } 21722 21723 // Legacy apps have the permission and get user consent on launch. 21724 PermissionsState permissionsState = packageSetting.getPermissionsState(); 21725 return permissionsState.isPermissionReviewRequired(userId); 21726 } 21727 } 21728 21729 @Override 21730 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 21731 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 21732 } 21733 21734 @Override 21735 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 21736 int userId) { 21737 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 21738 } 21739 21740 @Override 21741 public void setDeviceAndProfileOwnerPackages( 21742 int deviceOwnerUserId, String deviceOwnerPackage, 21743 SparseArray<String> profileOwnerPackages) { 21744 mProtectedPackages.setDeviceAndProfileOwnerPackages( 21745 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 21746 } 21747 21748 @Override 21749 public boolean isPackageDataProtected(int userId, String packageName) { 21750 return mProtectedPackages.isPackageDataProtected(userId, packageName); 21751 } 21752 21753 @Override 21754 public boolean isPackageEphemeral(int userId, String packageName) { 21755 synchronized (mPackages) { 21756 PackageParser.Package p = mPackages.get(packageName); 21757 return p != null ? p.applicationInfo.isEphemeralApp() : false; 21758 } 21759 } 21760 21761 @Override 21762 public boolean wasPackageEverLaunched(String packageName, int userId) { 21763 synchronized (mPackages) { 21764 return mSettings.wasPackageEverLaunchedLPr(packageName, userId); 21765 } 21766 } 21767 21768 @Override 21769 public void grantRuntimePermission(String packageName, String name, int userId, 21770 boolean overridePolicy) { 21771 PackageManagerService.this.grantRuntimePermission(packageName, name, userId, 21772 overridePolicy); 21773 } 21774 21775 @Override 21776 public void revokeRuntimePermission(String packageName, String name, int userId, 21777 boolean overridePolicy) { 21778 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId, 21779 overridePolicy); 21780 } 21781 21782 @Override 21783 public String getNameForUid(int uid) { 21784 return PackageManagerService.this.getNameForUid(uid); 21785 } 21786 21787 @Override 21788 public void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj, 21789 Intent origIntent, String resolvedType, Intent launchIntent, 21790 String callingPackage, int userId) { 21791 PackageManagerService.this.requestEphemeralResolutionPhaseTwo( 21792 responseObj, origIntent, resolvedType, launchIntent, callingPackage, userId); 21793 } 21794 21795 public String getSetupWizardPackageName() { 21796 return mSetupWizardPackage; 21797 } 21798 } 21799 21800 @Override 21801 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 21802 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 21803 synchronized (mPackages) { 21804 final long identity = Binder.clearCallingIdentity(); 21805 try { 21806 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 21807 packageNames, userId); 21808 } finally { 21809 Binder.restoreCallingIdentity(identity); 21810 } 21811 } 21812 } 21813 21814 private static void enforceSystemOrPhoneCaller(String tag) { 21815 int callingUid = Binder.getCallingUid(); 21816 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 21817 throw new SecurityException( 21818 "Cannot call " + tag + " from UID " + callingUid); 21819 } 21820 } 21821 21822 boolean isHistoricalPackageUsageAvailable() { 21823 return mPackageUsage.isHistoricalPackageUsageAvailable(); 21824 } 21825 21826 /** 21827 * Return a <b>copy</b> of the collection of packages known to the package manager. 21828 * @return A copy of the values of mPackages. 21829 */ 21830 Collection<PackageParser.Package> getPackages() { 21831 synchronized (mPackages) { 21832 return new ArrayList<>(mPackages.values()); 21833 } 21834 } 21835 21836 /** 21837 * Logs process start information (including base APK hash) to the security log. 21838 * @hide 21839 */ 21840 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 21841 String apkFile, int pid) { 21842 if (!SecurityLog.isLoggingEnabled()) { 21843 return; 21844 } 21845 Bundle data = new Bundle(); 21846 data.putLong("startTimestamp", System.currentTimeMillis()); 21847 data.putString("processName", processName); 21848 data.putInt("uid", uid); 21849 data.putString("seinfo", seinfo); 21850 data.putString("apkFile", apkFile); 21851 data.putInt("pid", pid); 21852 Message msg = mProcessLoggingHandler.obtainMessage( 21853 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 21854 msg.setData(data); 21855 mProcessLoggingHandler.sendMessage(msg); 21856 } 21857 21858 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 21859 return mCompilerStats.getPackageStats(pkgName); 21860 } 21861 21862 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 21863 return getOrCreateCompilerPackageStats(pkg.packageName); 21864 } 21865 21866 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 21867 return mCompilerStats.getOrCreatePackageStats(pkgName); 21868 } 21869 21870 public void deleteCompilerPackageStats(String pkgName) { 21871 mCompilerStats.deletePackageStats(pkgName); 21872 } 21873 21874 @Override 21875 public int getInstallReason(String packageName, int userId) { 21876 enforceCrossUserPermission(Binder.getCallingUid(), userId, 21877 true /* requireFullPermission */, false /* checkShell */, 21878 "get install reason"); 21879 synchronized (mPackages) { 21880 final PackageSetting ps = mSettings.mPackages.get(packageName); 21881 if (ps != null) { 21882 return ps.getInstallReason(userId); 21883 } 21884 } 21885 return PackageManager.INSTALL_REASON_UNKNOWN; 21886 } 21887} 21888